aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml2
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md1
-rw-r--r--.travis.yml4
-rw-r--r--CMakeLists.txt2
-rw-r--r--Changelog.md9
-rw-r--r--README.md3
-rw-r--r--cmake/templates/license.h.in2
-rw-r--r--docs/frequently-asked-questions.rst62
-rw-r--r--docs/installing-solidity.rst2
-rw-r--r--docs/introduction-to-smart-contracts.rst2
-rw-r--r--docs/miscellaneous.rst6
-rw-r--r--docs/resources.rst6
-rw-r--r--docs/types.rst6
-rw-r--r--libdevcore/CMakeLists.txt16
-rw-r--r--libdevcore/JSON.cpp8
-rw-r--r--libdevcore/JSON.h7
-rw-r--r--libevmasm/Assembly.cpp1
-rw-r--r--libevmasm/Assembly.h8
-rw-r--r--libevmasm/AssemblyItem.cpp2
-rw-r--r--libevmasm/AssemblyItem.h14
-rw-r--r--libevmasm/CMakeLists.txt22
-rw-r--r--libevmasm/CommonSubexpressionEliminator.cpp1
-rw-r--r--libevmasm/CommonSubexpressionEliminator.h9
-rw-r--r--libevmasm/ConstantOptimiser.h14
-rw-r--r--libevmasm/ControlFlowGraph.cpp2
-rw-r--r--libevmasm/ExpressionClasses.cpp2
-rw-r--r--libevmasm/ExpressionClasses.h7
-rw-r--r--libevmasm/GasMeter.h2
-rw-r--r--libevmasm/KnownState.cpp1
-rw-r--r--libevmasm/KnownState.h21
-rw-r--r--libevmasm/PathGasMeter.h2
-rw-r--r--libevmasm/SimplificationRules.cpp2
-rw-r--r--libevmasm/SimplificationRules.h9
-rw-r--r--liblangutil/CMakeLists.txt12
-rw-r--r--liblangutil/CharStream.cpp108
-rw-r--r--liblangutil/CharStream.h97
-rw-r--r--liblangutil/EVMVersion.h (renamed from libsolidity/interface/EVMVersion.h)0
-rw-r--r--liblangutil/ErrorReporter.cpp (renamed from libsolidity/interface/ErrorReporter.cpp)6
-rw-r--r--liblangutil/ErrorReporter.h (renamed from libsolidity/interface/ErrorReporter.h)12
-rw-r--r--liblangutil/Exceptions.cpp (renamed from libsolidity/interface/Exceptions.cpp)4
-rw-r--r--liblangutil/Exceptions.h (renamed from libsolidity/interface/Exceptions.h)27
-rw-r--r--liblangutil/ParserBase.cpp (renamed from libsolidity/parsing/ParserBase.cpp)9
-rw-r--r--liblangutil/ParserBase.h (renamed from libsolidity/parsing/ParserBase.h)8
-rw-r--r--liblangutil/Scanner.cpp (renamed from libsolidity/parsing/Scanner.cpp)128
-rw-r--r--liblangutil/Scanner.h (renamed from libsolidity/parsing/Scanner.h)71
-rw-r--r--liblangutil/SourceLocation.h (renamed from libevmasm/SourceLocation.h)4
-rw-r--r--liblangutil/SourceReferenceFormatter.cpp (renamed from libsolidity/interface/SourceReferenceFormatter.cpp)18
-rw-r--r--liblangutil/SourceReferenceFormatter.h (renamed from libsolidity/interface/SourceReferenceFormatter.h)21
-rw-r--r--liblangutil/Token.cpp (renamed from libsolidity/parsing/Token.cpp)9
-rw-r--r--liblangutil/Token.h376
-rw-r--r--liblangutil/UndefMacros.h (renamed from libsolidity/parsing/UndefMacros.h)0
-rw-r--r--liblll/CMakeLists.txt10
-rw-r--r--liblll/CodeFragment.cpp39
-rw-r--r--liblll/Compiler.h2
-rw-r--r--libsolidity/CMakeLists.txt59
-rw-r--r--libsolidity/analysis/ConstantEvaluator.cpp2
-rw-r--r--libsolidity/analysis/ConstantEvaluator.h10
-rw-r--r--libsolidity/analysis/ControlFlowAnalyzer.cpp2
-rw-r--r--libsolidity/analysis/ControlFlowAnalyzer.h6
-rw-r--r--libsolidity/analysis/ControlFlowBuilder.h28
-rw-r--r--libsolidity/analysis/ControlFlowGraph.cpp3
-rw-r--r--libsolidity/analysis/ControlFlowGraph.h10
-rw-r--r--libsolidity/analysis/DocStringAnalyser.cpp3
-rw-r--r--libsolidity/analysis/DocStringAnalyser.h19
-rw-r--r--libsolidity/analysis/NameAndTypeResolver.cpp9
-rw-r--r--libsolidity/analysis/NameAndTypeResolver.h19
-rw-r--r--libsolidity/analysis/PostTypeChecker.cpp3
-rw-r--r--libsolidity/analysis/PostTypeChecker.h24
-rw-r--r--libsolidity/analysis/ReferencesResolver.cpp26
-rw-r--r--libsolidity/analysis/ReferencesResolver.h55
-rw-r--r--libsolidity/analysis/SemVerHandler.h3
-rw-r--r--libsolidity/analysis/StaticAnalyzer.cpp3
-rw-r--r--libsolidity/analysis/StaticAnalyzer.h33
-rw-r--r--libsolidity/analysis/SyntaxChecker.cpp3
-rw-r--r--libsolidity/analysis/SyntaxChecker.h51
-rw-r--r--libsolidity/analysis/TypeChecker.cpp58
-rw-r--r--libsolidity/analysis/TypeChecker.h71
-rw-r--r--libsolidity/analysis/ViewPureChecker.cpp35
-rw-r--r--libsolidity/analysis/ViewPureChecker.h42
-rw-r--r--libsolidity/ast/AST.h278
-rw-r--r--libsolidity/ast/ASTAnnotations.h16
-rw-r--r--libsolidity/ast/ASTEnums.h2
-rw-r--r--libsolidity/ast/ASTJsonConverter.cpp9
-rw-r--r--libsolidity/ast/ASTJsonConverter.h11
-rw-r--r--libsolidity/ast/ASTPrinter.cpp1
-rw-r--r--libsolidity/ast/ASTVisitor.h4
-rw-r--r--libsolidity/ast/Types.cpp20
-rw-r--r--libsolidity/ast/Types.h537
-rw-r--r--libsolidity/codegen/ABIFunctions.h2
-rw-r--r--libsolidity/codegen/ArrayUtils.cpp3
-rw-r--r--libsolidity/codegen/Compiler.h2
-rw-r--r--libsolidity/codegen/CompilerContext.cpp37
-rw-r--r--libsolidity/codegen/CompilerContext.h2
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp1
-rw-r--r--libsolidity/codegen/ContractCompiler.cpp13
-rw-r--r--libsolidity/codegen/ContractCompiler.h32
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp4
-rw-r--r--libsolidity/codegen/ExpressionCompiler.h26
-rw-r--r--libsolidity/codegen/LValue.cpp1
-rw-r--r--libsolidity/codegen/LValue.h54
-rw-r--r--libsolidity/formal/CVC4Interface.cpp73
-rw-r--r--libsolidity/formal/CVC4Interface.h10
-rw-r--r--libsolidity/formal/SMTChecker.cpp73
-rw-r--r--libsolidity/formal/SMTChecker.h74
-rw-r--r--libsolidity/formal/SMTLib2Interface.cpp104
-rw-r--r--libsolidity/formal/SMTLib2Interface.h23
-rw-r--r--libsolidity/formal/SMTPortfolio.cpp25
-rw-r--r--libsolidity/formal/SMTPortfolio.h10
-rw-r--r--libsolidity/formal/SolverInterface.h201
-rw-r--r--libsolidity/formal/SymbolicTypes.cpp73
-rw-r--r--libsolidity/formal/SymbolicTypes.h16
-rw-r--r--libsolidity/formal/SymbolicVariables.cpp31
-rw-r--r--libsolidity/formal/SymbolicVariables.h23
-rw-r--r--libsolidity/formal/Z3Interface.cpp51
-rw-r--r--libsolidity/formal/Z3Interface.h9
-rw-r--r--libsolidity/inlineasm/AsmPrinter.h68
-rw-r--r--libsolidity/interface/AssemblyStack.cpp42
-rw-r--r--libsolidity/interface/AssemblyStack.h33
-rw-r--r--libsolidity/interface/CompilerStack.cpp13
-rw-r--r--libsolidity/interface/CompilerStack.h36
-rw-r--r--libsolidity/interface/GasEstimator.cpp1
-rw-r--r--libsolidity/interface/GasEstimator.h2
-rw-r--r--libsolidity/interface/StandardCompiler.cpp30
-rw-r--r--libsolidity/interface/Version.cpp2
-rw-r--r--libsolidity/parsing/DocStringParser.cpp5
-rw-r--r--libsolidity/parsing/DocStringParser.h11
-rw-r--r--libsolidity/parsing/Parser.cpp17
-rw-r--r--libsolidity/parsing/Parser.h17
-rw-r--r--libsolidity/parsing/Token.h394
-rw-r--r--libyul/ASTDataForward.h55
-rw-r--r--libyul/AsmAnalysis.cpp (renamed from libsolidity/inlineasm/AsmAnalysis.cpp)44
-rw-r--r--libyul/AsmAnalysis.h (renamed from libsolidity/inlineasm/AsmAnalysis.h)79
-rw-r--r--libyul/AsmAnalysisInfo.cpp (renamed from libsolidity/inlineasm/AsmAnalysisInfo.cpp)4
-rw-r--r--libyul/AsmAnalysisInfo.h (renamed from libsolidity/inlineasm/AsmAnalysisInfo.h)14
-rw-r--r--libyul/AsmCodeGen.cpp (renamed from libsolidity/inlineasm/AsmCodeGen.cpp)30
-rw-r--r--libyul/AsmCodeGen.h (renamed from libsolidity/inlineasm/AsmCodeGen.h)12
-rw-r--r--libyul/AsmData.h (renamed from libsolidity/inlineasm/AsmData.h)56
-rw-r--r--libyul/AsmDataForward.h (renamed from libsolidity/inlineasm/AsmDataForward.h)8
-rw-r--r--libyul/AsmParser.cpp (renamed from libsolidity/inlineasm/AsmParser.cpp)75
-rw-r--r--libyul/AsmParser.h (renamed from libsolidity/inlineasm/AsmParser.h)30
-rw-r--r--libyul/AsmPrinter.cpp (renamed from libsolidity/inlineasm/AsmPrinter.cpp)30
-rw-r--r--libyul/AsmPrinter.h62
-rw-r--r--libyul/AsmScope.cpp (renamed from libsolidity/inlineasm/AsmScope.cpp)14
-rw-r--r--libyul/AsmScope.h (renamed from libsolidity/inlineasm/AsmScope.h)30
-rw-r--r--libyul/AsmScopeFiller.cpp (renamed from libsolidity/inlineasm/AsmScopeFiller.cpp)19
-rw-r--r--libyul/AsmScopeFiller.h (renamed from libsolidity/inlineasm/AsmScopeFiller.h)54
-rw-r--r--libyul/CMakeLists.txt43
-rw-r--r--libyul/Exceptions.h7
-rw-r--r--libyul/YulString.h3
-rw-r--r--libyul/backends/evm/AbstractAssembly.h27
-rw-r--r--libyul/backends/evm/EVMAssembly.cpp5
-rw-r--r--libyul/backends/evm/EVMAssembly.h44
-rw-r--r--libyul/backends/evm/EVMCodeTransform.cpp24
-rw-r--r--libyul/backends/evm/EVMCodeTransform.h36
-rw-r--r--libyul/optimiser/ASTCopier.cpp4
-rw-r--r--libyul/optimiser/ASTCopier.h35
-rw-r--r--libyul/optimiser/ASTWalker.cpp4
-rw-r--r--libyul/optimiser/ASTWalker.h5
-rw-r--r--libyul/optimiser/BlockFlattener.cpp4
-rw-r--r--libyul/optimiser/BlockFlattener.h3
-rw-r--r--libyul/optimiser/CommonSubexpressionEliminator.cpp5
-rw-r--r--libyul/optimiser/CommonSubexpressionEliminator.h5
-rw-r--r--libyul/optimiser/DataFlowAnalyzer.cpp5
-rw-r--r--libyul/optimiser/DataFlowAnalyzer.h18
-rw-r--r--libyul/optimiser/Disambiguator.cpp9
-rw-r--r--libyul/optimiser/Disambiguator.h29
-rw-r--r--libyul/optimiser/ExpressionInliner.cpp5
-rw-r--r--libyul/optimiser/ExpressionInliner.h10
-rw-r--r--libyul/optimiser/ExpressionJoiner.cpp5
-rw-r--r--libyul/optimiser/ExpressionJoiner.h6
-rw-r--r--libyul/optimiser/ExpressionSimplifier.cpp5
-rw-r--r--libyul/optimiser/ExpressionSimplifier.h5
-rw-r--r--libyul/optimiser/ExpressionSplitter.cpp5
-rw-r--r--libyul/optimiser/ExpressionSplitter.h17
-rw-r--r--libyul/optimiser/ForLoopInitRewriter.cpp43
-rw-r--r--libyul/optimiser/ForLoopInitRewriter.h36
-rw-r--r--libyul/optimiser/FullInliner.cpp5
-rw-r--r--libyul/optimiser/FullInliner.h15
-rw-r--r--libyul/optimiser/FunctionGrouper.cpp4
-rw-r--r--libyul/optimiser/FunctionGrouper.h5
-rw-r--r--libyul/optimiser/FunctionHoister.cpp5
-rw-r--r--libyul/optimiser/FunctionHoister.h6
-rw-r--r--libyul/optimiser/InlinableExpressionFunctionFinder.cpp5
-rw-r--r--libyul/optimiser/InlinableExpressionFunctionFinder.h11
-rw-r--r--libyul/optimiser/MainFunction.cpp4
-rw-r--r--libyul/optimiser/MainFunction.h5
-rw-r--r--libyul/optimiser/Metrics.cpp4
-rw-r--r--libyul/optimiser/Metrics.h7
-rw-r--r--libyul/optimiser/NameCollector.cpp4
-rw-r--r--libyul/optimiser/NameCollector.h9
-rw-r--r--libyul/optimiser/NameDispenser.cpp5
-rw-r--r--libyul/optimiser/NameDispenser.h5
-rw-r--r--libyul/optimiser/RedundantAssignEliminator.cpp5
-rw-r--r--libyul/optimiser/RedundantAssignEliminator.h6
-rw-r--r--libyul/optimiser/Rematerialiser.cpp5
-rw-r--r--libyul/optimiser/Rematerialiser.h5
-rw-r--r--libyul/optimiser/SSATransform.cpp6
-rw-r--r--libyul/optimiser/SSATransform.h6
-rw-r--r--libyul/optimiser/SSAValueTracker.cpp4
-rw-r--r--libyul/optimiser/SSAValueTracker.h7
-rw-r--r--libyul/optimiser/Semantics.cpp5
-rw-r--r--libyul/optimiser/Semantics.h11
-rw-r--r--libyul/optimiser/SimplificationRules.cpp12
-rw-r--r--libyul/optimiser/SimplificationRules.h24
-rw-r--r--libyul/optimiser/Substitution.cpp4
-rw-r--r--libyul/optimiser/Substitution.h6
-rw-r--r--libyul/optimiser/Suite.cpp14
-rw-r--r--libyul/optimiser/Suite.h16
-rw-r--r--libyul/optimiser/SyntacticalEquality.cpp5
-rw-r--r--libyul/optimiser/SyntacticalEquality.h5
-rw-r--r--libyul/optimiser/UnusedPruner.cpp5
-rw-r--r--libyul/optimiser/UnusedPruner.h5
-rw-r--r--libyul/optimiser/Utilities.cpp6
-rw-r--r--libyul/optimiser/Utilities.h5
-rw-r--r--libyul/optimiser/VarDeclPropagator.cpp7
-rw-r--r--libyul/optimiser/VarDeclPropagator.h7
-rwxr-xr-xscripts/build_emscripten.sh2
-rwxr-xr-xscripts/bytecodecompare/storebytecode.sh16
-rwxr-xr-xscripts/travis-emscripten/build_emscripten.sh27
-rwxr-xr-xscripts/travis-emscripten/install_deps.sh18
-rw-r--r--solc/CommandLineInterface.cpp206
-rw-r--r--solc/CommandLineInterface.h2
-rw-r--r--test/CMakeLists.txt5
-rw-r--r--test/ExecutionFramework.h2
-rw-r--r--test/Options.cpp4
-rw-r--r--test/Options.h2
-rw-r--r--test/RPCSession.cpp2
-rw-r--r--test/TestCase.cpp (renamed from test/libsolidity/TestCase.cpp)2
-rw-r--r--test/TestCase.h (renamed from test/libsolidity/TestCase.h)0
-rw-r--r--test/boostTest.cpp12
-rw-r--r--test/contracts/AuctionRegistrar.cpp2
-rw-r--r--test/libevmasm/Assembler.cpp1
-rw-r--r--test/libevmasm/Optimiser.cpp1
-rw-r--r--test/liblangutil/SourceLocation.cpp (renamed from test/libevmasm/SourceLocation.cpp)7
-rw-r--r--test/liblll/EndToEndTest.cpp13
-rw-r--r--test/libsolidity/ABIDecoderTests.cpp2
-rw-r--r--test/libsolidity/ABIEncoderTests.cpp2
-rw-r--r--test/libsolidity/ASTJSONTest.h8
-rw-r--r--test/libsolidity/AnalysisFramework.cpp7
-rw-r--r--test/libsolidity/AnalysisFramework.h8
-rw-r--r--test/libsolidity/Assembly.cpp7
-rw-r--r--test/libsolidity/ErrorCheck.cpp1
-rw-r--r--test/libsolidity/ErrorCheck.h6
-rw-r--r--test/libsolidity/GasMeter.cpp3
-rw-r--r--test/libsolidity/Imports.cpp2
-rw-r--r--test/libsolidity/InlineAssembly.cpp5
-rw-r--r--test/libsolidity/SMTChecker.cpp594
-rw-r--r--test/libsolidity/SMTCheckerJSONTest.cpp128
-rw-r--r--test/libsolidity/SMTCheckerJSONTest.h53
-rw-r--r--test/libsolidity/SemVerMatcher.cpp3
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp38
-rw-r--r--test/libsolidity/SolidityExecutionFramework.h10
-rw-r--r--test/libsolidity/SolidityExpressionCompiler.cpp5
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp1
-rw-r--r--test/libsolidity/SolidityNatspecJSON.cpp4
-rw-r--r--test/libsolidity/SolidityParser.cpp5
-rw-r--r--test/libsolidity/SolidityScanner.cpp16
-rw-r--r--test/libsolidity/SolidityTypes.cpp1
-rw-r--r--test/libsolidity/SyntaxTest.cpp6
-rw-r--r--test/libsolidity/SyntaxTest.h14
-rw-r--r--test/libsolidity/ViewPureChecker.cpp1
-rw-r--r--test/libsolidity/smtCheckerTests/complex/warn_on_struct.sol14
-rw-r--r--test/libsolidity/smtCheckerTests/complex/warn_on_typecast.sol8
-rw-r--r--test/libsolidity/smtCheckerTests/control_flow/assignment_in_declaration.sol4
-rw-r--r--test/libsolidity/smtCheckerTests/control_flow/branches_assert_condition_1.sol12
-rw-r--r--test/libsolidity/smtCheckerTests/control_flow/branches_assert_condition_2.sol16
-rw-r--r--test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_1.sol10
-rw-r--r--test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_2.sol11
-rw-r--r--test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_3.sol12
-rw-r--r--test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_4.sol13
-rw-r--r--test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_5.sol13
-rw-r--r--test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_6.sol13
-rw-r--r--test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_1.sol12
-rw-r--r--test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_2.sol12
-rw-r--r--test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_3.sol12
-rw-r--r--test/libsolidity/smtCheckerTests/functions/function_call_does_not_clear_local_vars.sol13
-rw-r--r--test/libsolidity/smtCheckerTests/functions/functions_bound_1.sol19
-rw-r--r--test/libsolidity/smtCheckerTests/functions/functions_bound_1_fail.sol21
-rw-r--r--test/libsolidity/smtCheckerTests/functions/functions_library_1.sol18
-rw-r--r--test/libsolidity/smtCheckerTests/functions/functions_library_1_fail.sol20
-rw-r--r--test/libsolidity/smtCheckerTests/loops/for_loop_1.sol8
-rw-r--r--test/libsolidity/smtCheckerTests/loops/for_loop_2.sol8
-rw-r--r--test/libsolidity/smtCheckerTests/loops/for_loop_3.sol8
-rw-r--r--test/libsolidity/smtCheckerTests/loops/for_loop_4.sol10
-rw-r--r--test/libsolidity/smtCheckerTests/loops/for_loop_5.sol12
-rw-r--r--test/libsolidity/smtCheckerTests/loops/for_loop_6.sol12
-rw-r--r--test/libsolidity/smtCheckerTests/loops/while_loop_simple_1.sol13
-rw-r--r--test/libsolidity/smtCheckerTests/loops/while_loop_simple_2.sol9
-rw-r--r--test/libsolidity/smtCheckerTests/loops/while_loop_simple_3.sol11
-rw-r--r--test/libsolidity/smtCheckerTests/loops/while_loop_simple_4.sol11
-rw-r--r--test/libsolidity/smtCheckerTests/loops/while_loop_simple_5.sol12
-rw-r--r--test/libsolidity/smtCheckerTests/overflow/simple_overflow.sol6
-rw-r--r--test/libsolidity/smtCheckerTests/simple/smoke_test.sol3
-rw-r--r--test/libsolidity/smtCheckerTests/special/blockhash.sol8
-rw-r--r--test/libsolidity/smtCheckerTests/types/bool_int_mixed_1.sol9
-rw-r--r--test/libsolidity/smtCheckerTests/types/bool_int_mixed_2.sol8
-rw-r--r--test/libsolidity/smtCheckerTests/types/bool_int_mixed_3.sol21
-rw-r--r--test/libsolidity/smtCheckerTests/types/bool_simple_1.sol8
-rw-r--r--test/libsolidity/smtCheckerTests/types/bool_simple_2.sol8
-rw-r--r--test/libsolidity/smtCheckerTests/types/bool_simple_3.sol7
-rw-r--r--test/libsolidity/smtCheckerTests/types/bool_simple_4.sol10
-rw-r--r--test/libsolidity/smtCheckerTests/types/bool_simple_5.sol7
-rw-r--r--test/libsolidity/smtCheckerTests/types/bool_simple_6.sol9
-rw-r--r--test/libsolidity/smtCheckerTests/types/storage_value_vars_1.sol22
-rw-r--r--test/libsolidity/smtCheckerTests/types/storage_value_vars_2.sol12
-rw-r--r--test/libsolidity/smtCheckerTests/types/storage_value_vars_3.sol25
-rw-r--r--test/libsolidity/smtCheckerTests/types/storage_value_vars_4.sol10
-rw-r--r--test/libsolidity/smtCheckerTests/verification_target/constant_condition_1.sol9
-rw-r--r--test/libsolidity/smtCheckerTests/verification_target/constant_condition_2.sol9
-rw-r--r--test/libsolidity/smtCheckerTests/verification_target/constant_condition_3.sol9
-rw-r--r--test/libsolidity/smtCheckerTests/verification_target/simple_assert.sol6
-rw-r--r--test/libsolidity/smtCheckerTests/verification_target/simple_assert_with_require.sol4
-rw-r--r--test/libsolidity/smtCheckerTestsJSON/multi.json11
-rw-r--r--test/libsolidity/smtCheckerTestsJSON/multi.sol13
-rw-r--r--test/libsolidity/smtCheckerTestsJSON/simple.json9
-rw-r--r--test/libsolidity/smtCheckerTestsJSON/simple.sol10
-rw-r--r--test/libsolidity/syntaxTests/bound/bound_all.sol10
-rw-r--r--test/libsolidity/syntaxTests/bound/bound_call.sol7
-rw-r--r--test/libsolidity/syntaxTests/bound/bound_no_call.sol7
-rw-r--r--test/libsolidity/syntaxTests/inheritance/override/external_turns_public_no_params.sol7
-rw-r--r--test/libsolidity/syntaxTests/inheritance/super_on_external.sol10
-rw-r--r--test/libsolidity/syntaxTests/inlineAssembly/invalid/invalid_number.sol2
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/182_equal_overload.sol1
-rw-r--r--test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol2
-rw-r--r--test/libsolidity/syntaxTests/string/string_new_line.sol2
-rw-r--r--test/libsolidity/syntaxTests/string/string_terminated_by_backslash.sol2
-rw-r--r--test/libsolidity/syntaxTests/string/string_unterminated.sol2
-rw-r--r--test/libsolidity/syntaxTests/string/string_unterminated_no_new_line.sol2
-rw-r--r--test/libsolidity/syntaxTests/unicode_escape_literals.sol2
-rw-r--r--test/libyul/Common.cpp36
-rw-r--r--test/libyul/Common.h19
-rw-r--r--test/libyul/Inliner.cpp7
-rw-r--r--test/libyul/Parser.cpp27
-rw-r--r--test/libyul/YulOptimizerTest.cpp35
-rw-r--r--test/libyul/YulOptimizerTest.h22
-rw-r--r--test/libyul/yulOptimizerTests/forLoopInitRewriter/complex_pre.yul23
-rw-r--r--test/libyul/yulOptimizerTests/forLoopInitRewriter/empty_pre.yul20
-rw-r--r--test/libyul/yulOptimizerTests/forLoopInitRewriter/simple.yul21
-rw-r--r--test/tools/CMakeLists.txt4
-rw-r--r--test/tools/isoltest.cpp12
-rw-r--r--test/tools/yulopti.cpp34
341 files changed, 4438 insertions, 3417 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 0980fa5c..975d1c7a 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -53,7 +53,7 @@ jobs:
name: Save Boost build
key: *boost-cache-key
paths:
- - boost_1_57_0
+ - boost_1_67_0
- store_artifacts:
path: build/libsolc/soljson.js
destination: soljson.js
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index c3caf86e..dd4d0b41 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -21,6 +21,7 @@ about: Bug reports about the Solidity Compiler.
## Environment
- Compiler version:
+- Target EVM version (as per compiler settings):
- Framework/IDE (e.g. Truffle or Remix):
- EVM execution environment / backend / blockchain client:
- Operating system:
diff --git a/.travis.yml b/.travis.yml
index ef4f8b39..d68c79ba 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -90,7 +90,7 @@ matrix:
before_install:
- nvm install 8
- nvm use 8
- - docker pull trzeci/emscripten:sdk-tag-1.35.4-64bit
+ - docker pull trzeci/emscripten:sdk-tag-1.37.21-64bit
env:
- SOLC_EMSCRIPTEN=On
- SOLC_INSTALL_DEPS_TRAVIS=Off
@@ -153,7 +153,7 @@ git:
cache:
ccache: true
directories:
- - boost_1_57_0
+ - boost_1_67_0
- $HOME/.local
install:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 86769672..b22ade23 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,7 +45,9 @@ include(EthOptions)
configure_project(TESTS)
add_subdirectory(libdevcore)
+add_subdirectory(liblangutil)
add_subdirectory(libevmasm)
+add_subdirectory(libyul)
add_subdirectory(libsolidity)
add_subdirectory(libsolc)
diff --git a/Changelog.md b/Changelog.md
index b2b03ae4..e6f01553 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,14 +1,23 @@
### 0.5.1 (unreleased)
Language Features:
+ * Allow public functions to override external functions.
Compiler Features:
* Build System: LLL is not built anymore by default. Must configure it with CMake as `-DLLL=ON`.
* Code generator: Do not perform redundant double cleanup on unsigned integers when loading from calldata.
+ * SMTChecker: SMTLib2 queries and responses passed via standard JSON compiler interface.
+ * SMTChecker: Support ``msg``, ``tx`` and ``block`` member variables.
+ * SMTChecker: Support ``gasleft()`` and ``blockhash()`` functions.
+ * SMTChecker: Support internal bound function calls.
Bugfixes:
+ * Assembly output: Do not mix in/out jump annotations with arguments.
+
+Build System:
+ * Emscripten: Upgrade to Emscripten SDK 1.37.21 and boost 1.67.
diff --git a/README.md b/README.md
index 7a448e8c..c7065c09 100644
--- a/README.md
+++ b/README.md
@@ -62,5 +62,6 @@ if you want to help.
[@chriseth](https://github.com/chriseth)
## License
-Solidity is licensed under [GNU General Public License v3.0](https://github.com/ethereum/solidity/blob/develop/LICENSE.txt)
+Solidity is licensed under [GNU General Public License v3.0](LICENSE.txt)
+Some third-party code has its [own licensing terms](cmake/templates/license.h.in).
diff --git a/cmake/templates/license.h.in b/cmake/templates/license.h.in
index 4f22d8f4..31e2e17d 100644
--- a/cmake/templates/license.h.in
+++ b/cmake/templates/license.h.in
@@ -67,7 +67,7 @@ jsoncpp:
license you like.
scanner/token:
- The libsolidity/parsing/{scanner,token}.{h,cpp} files are dervied from
+ The liblangutil/{CharStream,Scanner,Token}.{h,cpp} files are dervied from
code originating from the V8 project licensed under the following terms:
Copyright 2006-2012, the V8 project authors. All rights reserved.
diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst
index a569a896..9cc08822 100644
--- a/docs/frequently-asked-questions.rst
+++ b/docs/frequently-asked-questions.rst
@@ -194,24 +194,6 @@ Note2: Optimizing storage access can pull the gas costs down considerably, becau
currently do not work across loops and also have a problem with bounds checking.
You might get much better results in the future, though.
-What happens to a ``struct``'s mapping when copying over a ``struct``?
-======================================================================
-
-This is a very interesting question. Suppose that we have a contract field set up like such::
-
- struct User {
- mapping(string => string) comments;
- }
-
- function somefunction public {
- User user1;
- user1.comments["Hello"] = "World";
- User user2 = user1;
- }
-
-In this case, the mapping of the struct being copied over into ``user2`` is ignored as there is no "list of mapped keys".
-Therefore it is not possible to find out which values should be copied over.
-
How do I initialize a contract with only a specific amount of wei?
==================================================================
@@ -287,50 +269,6 @@ to create an independent copy of the storage value in memory.
On the other hand, ``h(x)`` successfully modifies ``x`` because only
a reference and not a copy is passed.
-Sometimes, when I try to change the length of an array with ex: ``arrayname.length = 7;`` I get a compiler error ``Value must be an lvalue``. Why?
-==================================================================================================================================================
-
-You can resize a dynamic array in storage (i.e. an array declared at the
-contract level) with ``arrayname.length = <some new length>;``. If you get the
-"lvalue" error, you are probably doing one of two things wrong.
-
-1. You might be trying to resize an array in "memory", or
-
-2. You might be trying to resize a non-dynamic array.
-
-::
-
- pragma solidity >=0.4.18 <0.6.0;
-
- // This will not compile
- contract C {
- int8[] dynamicStorageArray;
- int8[5] fixedStorageArray;
-
- function f() public {
- int8[] memory memArr; // Case 1
- memArr.length++; // illegal
-
- int8[5] storage storageArr = fixedStorageArray; // Case 2
- storageArr.length++; // illegal
-
- int8[] storage storageArr2 = dynamicStorageArray;
- storageArr2.length++; // legal
-
-
- }
- }
-
-**Important note:** In Solidity, array dimensions are declared backwards from the way you
-might be used to declaring them in C or Java, but they are access as in
-C or Java.
-
-For example, ``int8[][5] somearray;`` are 5 dynamic ``int8`` arrays.
-
-The reason for this is that ``T[5]`` is always an array of 5 ``T``'s,
-no matter whether ``T`` itself is an array or not (this is not the
-case in C or Java).
-
Is it possible to return an array of strings (``string[]``) from a Solidity function?
=====================================================================================
diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst
index f8de0e8d..2797d8b0 100644
--- a/docs/installing-solidity.rst
+++ b/docs/installing-solidity.rst
@@ -115,7 +115,7 @@ Arch Linux also has packages, albeit limited to the latest development version:
pacman -S solidity
-We distribute the Solidity compiler through Homebrow
+We distribute the Solidity compiler through Homebrew
as a build-from-source version. Pre-built bottles are
currently not supported.
diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst
index 9245300b..34ef012e 100644
--- a/docs/introduction-to-smart-contracts.rst
+++ b/docs/introduction-to-smart-contracts.rst
@@ -400,7 +400,7 @@ within a word). At the time of expansion, the cost in gas must be paid. Memory i
costly the larger it grows (it scales quadratically).
The EVM is not a register machine but a stack machine, so all
-computations are performed on an data area called the **stack**. It has a maximum size of
+computations are performed on a data area called the **stack**. It has a maximum size of
1024 elements and contains words of 256 bits. Access to the stack is
limited to the top end in the following way:
It is possible to copy one of
diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst
index 21978ded..017d5b81 100644
--- a/docs/miscellaneous.rst
+++ b/docs/miscellaneous.rst
@@ -8,13 +8,17 @@ Miscellaneous
Layout of State Variables in Storage
************************************
-Statically-sized variables (everything except mapping and dynamically-sized array types) are laid out contiguously in storage starting from position ``0``. Multiple items that need less than 32 bytes are packed into a single storage slot if possible, according to the following rules:
+Statically-sized variables (everything except mapping and dynamically-sized array types) are laid out contiguously in storage starting from position ``0``. Multiple, contiguous items that need less than 32 bytes are packed into a single storage slot if possible, according to the following rules:
- The first item in a storage slot is stored lower-order aligned.
- Elementary types use only that many bytes that are necessary to store them.
- If an elementary type does not fit the remaining part of a storage slot, it is moved to the next storage slot.
- Structs and array data always start a new slot and occupy whole slots (but items inside a struct or array are packed tightly according to these rules).
+For contracts that use inheritance, the ordering of state variables is determined by the
+C3-linearized order of contracts starting with the most base-ward contract. If allowed
+by the above rules, state variables from different contracts do share the same storage slot.
+
.. warning::
When using elements that are smaller than 32 bytes, your contract's gas usage may be higher.
This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller
diff --git a/docs/resources.rst b/docs/resources.rst
index e9e65692..4dd617fa 100644
--- a/docs/resources.rst
+++ b/docs/resources.rst
@@ -21,9 +21,8 @@ Solidity Integrations
* Generic:
-
* `EthFiddle <https://ethfiddle.com/>`_
- Solidity IDE in the Browser. Write and share your solidity code. Uses server-side components.
+ Solidity IDE in the Browser. Write and share your Solidity code. Uses server-side components.
* `Remix <https://remix.ethereum.org/>`_
Browser-based IDE with integrated compiler and Solidity runtime environment without server-side components.
@@ -34,6 +33,9 @@ Solidity Integrations
* `Solhint <https://github.com/protofire/solhint>`_
Solidity linter that provides security, style guide and best practice rules for smart contract validation.
+ * `Superblocks Lab <https://lab.superblocks.com/>`_
+ Browser-based IDE. Built-in browser-based VM and Metamask integration (one click deployment to Testnet/Mainnet).
+
* Atom:
* `Etheratom <https://github.com/0mkara/etheratom>`_
diff --git a/docs/types.rst b/docs/types.rst
index 39238f8f..69c846a6 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -278,7 +278,7 @@ Example::
when the call returns. The regular way to interact with other contracts
is to call a function on a contract object (``x.f()``).
-:: note::
+.. note::
Previous versions of Solidity allowed these functions to receive
arbitrary arguments and would also handle a first argument of type
``bytes4`` differently. These edge cases were removed in version 0.5.0.
@@ -918,7 +918,9 @@ Members
For dynamically-sized arrays (only available for storage), this member can be assigned to resize the array.
Accessing elements outside the current length does not automatically resize the array and instead causes a failing assertion.
Increasing the length adds new zero-initialised elements to the array.
- Reducing the length performs an implicit :ref:``delete`` on each of the removed elements.
+ Reducing the length performs an implicit :ref:``delete`` on each of the
+ removed elements. If you try to resize a non-dynamic array that isn't in
+ storage, you receive a ``Value must be an lvalue`` error.
**push**:
Dynamic storage arrays and ``bytes`` (not ``string``) have a member function called ``push`` that you can use to append an element at the end of the array. The element will be zero-initialised. The function returns the new length.
**pop**:
diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt
index fa7e3f48..01a8bcc6 100644
--- a/libdevcore/CMakeLists.txt
+++ b/libdevcore/CMakeLists.txt
@@ -1,7 +1,17 @@
-file(GLOB sources "*.cpp")
-file(GLOB headers "*.h")
+set(sources
+ CommonData.cpp
+ CommonIO.cpp
+ Exceptions.cpp
+ IndentedWriter.cpp
+ JSON.cpp
+ Keccak256.cpp
+ StringUtils.cpp
+ SwarmHash.cpp
+ UTF8.cpp
+ Whiskers.cpp
+)
-add_library(devcore ${sources} ${headers})
+add_library(devcore ${sources})
target_link_libraries(devcore PRIVATE jsoncpp ${Boost_FILESYSTEM_LIBRARIES} ${Boost_REGEX_LIBRARIES} ${Boost_SYSTEM_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(devcore PUBLIC "${CMAKE_SOURCE_DIR}")
target_include_directories(devcore SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
diff --git a/libdevcore/JSON.cpp b/libdevcore/JSON.cpp
index 6317cc89..086fae50 100644
--- a/libdevcore/JSON.cpp
+++ b/libdevcore/JSON.cpp
@@ -21,6 +21,8 @@
#include "JSON.h"
+#include "CommonIO.h"
+
#include <sstream>
#include <map>
#include <memory>
@@ -111,4 +113,10 @@ bool jsonParse(string const& _input, Json::Value& _json, string *_errs /* = null
return parse(readerBuilder, _input, _json, _errs);
}
+bool jsonParseFile(string const& _fileName, Json::Value& _json, string *_errs /* = nullptr */)
+{
+ return jsonParse(readFileAsString(_fileName), _json, _errs);
+}
+
+
} // namespace dev
diff --git a/libdevcore/JSON.h b/libdevcore/JSON.h
index 1ce822cd..ecb93467 100644
--- a/libdevcore/JSON.h
+++ b/libdevcore/JSON.h
@@ -48,4 +48,11 @@ bool jsonParseStrict(std::string const& _input, Json::Value& _json, std::string*
/// \return \c true if the document was successfully parsed, \c false if an error occurred.
bool jsonParse(std::string const& _input, Json::Value& _json, std::string* _errs = nullptr);
+/// Parse a JSON string (@a _input) and writes resulting JSON object to (@a _json)
+/// \param _input file containing JSON input
+/// \param _json [out] resulting JSON object
+/// \param _errs [out] Formatted error messages
+/// \return \c true if the document was successfully parsed, \c false if an error occurred.
+bool jsonParseFile(std::string const& _fileName, Json::Value& _json, std::string* _errs = nullptr);
+
}
diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp
index e63194a0..d80f97c4 100644
--- a/libevmasm/Assembly.cpp
+++ b/libevmasm/Assembly.cpp
@@ -35,6 +35,7 @@
using namespace std;
using namespace dev;
using namespace dev::eth;
+using namespace langutil;
void Assembly::append(Assembly const& _a)
{
diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h
index 8ef36923..d846b475 100644
--- a/libevmasm/Assembly.h
+++ b/libevmasm/Assembly.h
@@ -18,12 +18,12 @@
#pragma once
#include <libevmasm/Instruction.h>
-#include <libevmasm/SourceLocation.h>
+#include <liblangutil/SourceLocation.h>
#include <libevmasm/AssemblyItem.h>
#include <libevmasm/LinkerObject.h>
#include <libevmasm/Exceptions.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <libdevcore/Common.h>
#include <libdevcore/Assertions.h>
@@ -93,7 +93,7 @@ public:
void setDeposit(int _deposit) { m_deposit = _deposit; assertThrow(m_deposit >= 0, InvalidDeposit, ""); }
/// Changes the source location used for each appended item.
- void setSourceLocation(SourceLocation const& _location) { m_currentSourceLocation = _location; }
+ void setSourceLocation(langutil::SourceLocation const& _location) { m_currentSourceLocation = _location; }
/// Assembles the assembly into bytecode. The assembly should not be modified after this call, since the assembled version is cached.
LinkerObject const& assemble() const;
@@ -178,7 +178,7 @@ protected:
int m_deposit = 0;
- SourceLocation m_currentSourceLocation;
+ langutil::SourceLocation m_currentSourceLocation;
};
inline std::ostream& operator<<(std::ostream& _out, Assembly const& _a)
diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp
index a3a4d6b6..52f246d1 100644
--- a/libevmasm/AssemblyItem.cpp
+++ b/libevmasm/AssemblyItem.cpp
@@ -117,6 +117,8 @@ int AssemblyItem::returnValues() const
bool AssemblyItem::canBeFunctional() const
{
+ if (m_jumpType != JumpType::Ordinary)
+ return false;
switch (m_type)
{
case Operation:
diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h
index 6187e18f..a7875171 100644
--- a/libevmasm/AssemblyItem.h
+++ b/libevmasm/AssemblyItem.h
@@ -26,7 +26,7 @@
#include <libdevcore/Common.h>
#include <libdevcore/Assertions.h>
#include <libevmasm/Instruction.h>
-#include <libevmasm/SourceLocation.h>
+#include <liblangutil/SourceLocation.h>
#include "Exceptions.h"
using namespace dev::solidity;
@@ -57,14 +57,14 @@ class AssemblyItem
public:
enum class JumpType { Ordinary, IntoFunction, OutOfFunction };
- AssemblyItem(u256 _push, SourceLocation const& _location = SourceLocation()):
+ AssemblyItem(u256 _push, langutil::SourceLocation const& _location = langutil::SourceLocation()):
AssemblyItem(Push, _push, _location) { }
- AssemblyItem(solidity::Instruction _i, SourceLocation const& _location = SourceLocation()):
+ AssemblyItem(solidity::Instruction _i, langutil::SourceLocation const& _location = langutil::SourceLocation()):
m_type(Operation),
m_instruction(_i),
m_location(_location)
{}
- AssemblyItem(AssemblyItemType _type, u256 _data = 0, SourceLocation const& _location = SourceLocation()):
+ AssemblyItem(AssemblyItemType _type, u256 _data = 0, langutil::SourceLocation const& _location = langutil::SourceLocation()):
m_type(_type),
m_location(_location)
{
@@ -124,8 +124,8 @@ public:
/// @returns true if the assembly item can be used in a functional context.
bool canBeFunctional() const;
- void setLocation(SourceLocation const& _location) { m_location = _location; }
- SourceLocation const& location() const { return m_location; }
+ void setLocation(langutil::SourceLocation const& _location) { m_location = _location; }
+ langutil::SourceLocation const& location() const { return m_location; }
void setJumpType(JumpType _jumpType) { m_jumpType = _jumpType; }
JumpType getJumpType() const { return m_jumpType; }
@@ -140,7 +140,7 @@ private:
AssemblyItemType m_type;
Instruction m_instruction; ///< Only valid if m_type == Operation
std::shared_ptr<u256> m_data; ///< Only valid if m_type != Operation
- SourceLocation m_location;
+ langutil::SourceLocation m_location;
JumpType m_jumpType = JumpType::Ordinary;
/// Pushed value for operations with data to be determined during assembly stage,
/// e.g. PushSubSize, PushTag, PushSub, etc.
diff --git a/libevmasm/CMakeLists.txt b/libevmasm/CMakeLists.txt
index 86192c1b..e0e3389a 100644
--- a/libevmasm/CMakeLists.txt
+++ b/libevmasm/CMakeLists.txt
@@ -1,5 +1,21 @@
-file(GLOB sources "*.cpp")
-file(GLOB headers "*.h")
+set(sources
+ Assembly.cpp
+ AssemblyItem.cpp
+ BlockDeduplicator.cpp
+ CommonSubexpressionEliminator.cpp
+ ConstantOptimiser.cpp
+ ControlFlowGraph.cpp
+ ExpressionClasses.cpp
+ GasMeter.cpp
+ Instruction.cpp
+ JumpdestRemover.cpp
+ KnownState.cpp
+ LinkerObject.cpp
+ PathGasMeter.cpp
+ PeepholeOptimiser.cpp
+ SemanticInformation.cpp
+ SimplificationRules.cpp
+)
-add_library(evmasm ${sources} ${headers})
+add_library(evmasm ${sources})
target_link_libraries(evmasm PUBLIC devcore)
diff --git a/libevmasm/CommonSubexpressionEliminator.cpp b/libevmasm/CommonSubexpressionEliminator.cpp
index 04926986..949d2c75 100644
--- a/libevmasm/CommonSubexpressionEliminator.cpp
+++ b/libevmasm/CommonSubexpressionEliminator.cpp
@@ -30,6 +30,7 @@
using namespace std;
using namespace dev;
using namespace dev::eth;
+using namespace langutil;
vector<AssemblyItem> CommonSubexpressionEliminator::getOptimizedItems()
{
diff --git a/libevmasm/CommonSubexpressionEliminator.h b/libevmasm/CommonSubexpressionEliminator.h
index b20de246..eba25db0 100644
--- a/libevmasm/CommonSubexpressionEliminator.h
+++ b/libevmasm/CommonSubexpressionEliminator.h
@@ -34,6 +34,11 @@
#include <libevmasm/SemanticInformation.h>
#include <libevmasm/KnownState.h>
+namespace langutil
+{
+struct SourceLocation;
+}
+
namespace dev
{
namespace eth
@@ -137,10 +142,10 @@ private:
bool removeStackTopIfPossible();
/// Appends a dup instruction to m_generatedItems to retrieve the element at the given stack position.
- void appendDup(int _fromPosition, SourceLocation const& _location);
+ void appendDup(int _fromPosition, langutil::SourceLocation const& _location);
/// Appends a swap instruction to m_generatedItems to retrieve the element at the given stack position.
/// @note this might also remove the last item if it exactly the same swap instruction.
- void appendOrRemoveSwap(int _fromPosition, SourceLocation const& _location);
+ void appendOrRemoveSwap(int _fromPosition, langutil::SourceLocation const& _location);
/// Appends the given assembly item.
void appendItem(AssemblyItem const& _item);
diff --git a/libevmasm/ConstantOptimiser.h b/libevmasm/ConstantOptimiser.h
index 2c753fa8..04c43c5d 100644
--- a/libevmasm/ConstantOptimiser.h
+++ b/libevmasm/ConstantOptimiser.h
@@ -23,7 +23,7 @@
#include <libevmasm/Exceptions.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <libdevcore/Assertions.h>
#include <libdevcore/CommonData.h>
@@ -109,8 +109,8 @@ class LiteralMethod: public ConstantOptimisationMethod
public:
explicit LiteralMethod(Params const& _params, u256 const& _value):
ConstantOptimisationMethod(_params, _value) {}
- virtual bigint gasNeeded() const override;
- virtual AssemblyItems execute(Assembly&) const override { return AssemblyItems{}; }
+ bigint gasNeeded() const override;
+ AssemblyItems execute(Assembly&) const override { return AssemblyItems{}; }
};
/**
@@ -120,8 +120,8 @@ class CodeCopyMethod: public ConstantOptimisationMethod
{
public:
explicit CodeCopyMethod(Params const& _params, u256 const& _value);
- virtual bigint gasNeeded() const override;
- virtual AssemblyItems execute(Assembly& _assembly) const override;
+ bigint gasNeeded() const override;
+ AssemblyItems execute(Assembly& _assembly) const override;
protected:
static AssemblyItems const& copyRoutine();
@@ -144,8 +144,8 @@ public:
);
}
- virtual bigint gasNeeded() const override { return gasNeeded(m_routine); }
- virtual AssemblyItems execute(Assembly&) const override
+ bigint gasNeeded() const override { return gasNeeded(m_routine); }
+ AssemblyItems execute(Assembly&) const override
{
return m_routine;
}
diff --git a/libevmasm/ControlFlowGraph.cpp b/libevmasm/ControlFlowGraph.cpp
index 86f16d48..d62f5436 100644
--- a/libevmasm/ControlFlowGraph.cpp
+++ b/libevmasm/ControlFlowGraph.cpp
@@ -275,7 +275,7 @@ void ControlFlowGraph::gatherKnowledge()
//@todo in the case of JUMPI, add knowledge about the condition to the state
// (for both values of the condition)
set<u256> tags = state->tagsInExpression(
- state->stackElement(state->stackHeight(), SourceLocation())
+ state->stackElement(state->stackHeight(), langutil::SourceLocation{})
);
state->feedItem(m_items.at(pc++));
diff --git a/libevmasm/ExpressionClasses.cpp b/libevmasm/ExpressionClasses.cpp
index 42a1819a..abbbbc2c 100644
--- a/libevmasm/ExpressionClasses.cpp
+++ b/libevmasm/ExpressionClasses.cpp
@@ -34,7 +34,7 @@
using namespace std;
using namespace dev;
using namespace dev::eth;
-
+using namespace langutil;
bool ExpressionClasses::Expression::operator<(ExpressionClasses::Expression const& _other) const
{
diff --git a/libevmasm/ExpressionClasses.h b/libevmasm/ExpressionClasses.h
index df8082f9..a34844c5 100644
--- a/libevmasm/ExpressionClasses.h
+++ b/libevmasm/ExpressionClasses.h
@@ -31,6 +31,11 @@
#include <memory>
#include <set>
+namespace langutil
+{
+struct SourceLocation;
+}
+
namespace dev
{
namespace eth
@@ -82,7 +87,7 @@ public:
void forceEqual(Id _id, AssemblyItem const& _item, Ids const& _arguments, bool _copyItem = true);
/// @returns the id of a new class which is different to all other classes.
- Id newClass(SourceLocation const& _location);
+ Id newClass(langutil::SourceLocation const& _location);
/// @returns true if the values of the given classes are known to be different (on every input).
/// @note that this function might still return false for some different inputs.
diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h
index da90b028..e3909e86 100644
--- a/libevmasm/GasMeter.h
+++ b/libevmasm/GasMeter.h
@@ -24,7 +24,7 @@
#include <libevmasm/ExpressionClasses.h>
#include <libevmasm/AssemblyItem.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <ostream>
#include <tuple>
diff --git a/libevmasm/KnownState.cpp b/libevmasm/KnownState.cpp
index b6c1bcc9..a5546e61 100644
--- a/libevmasm/KnownState.cpp
+++ b/libevmasm/KnownState.cpp
@@ -29,6 +29,7 @@
using namespace std;
using namespace dev;
using namespace dev::eth;
+using namespace langutil;
ostream& KnownState::stream(ostream& _out) const
{
diff --git a/libevmasm/KnownState.h b/libevmasm/KnownState.h
index cd50550e..3ab1c4b1 100644
--- a/libevmasm/KnownState.h
+++ b/libevmasm/KnownState.h
@@ -46,6 +46,11 @@
#include <libevmasm/ExpressionClasses.h>
#include <libevmasm/SemanticInformation.h>
+namespace langutil
+{
+struct SourceLocation;
+}
+
namespace dev
{
namespace eth
@@ -121,9 +126,9 @@ public:
/// Retrieves the current equivalence class fo the given stack element (or generates a new
/// one if it does not exist yet).
- Id stackElement(int _stackHeight, SourceLocation const& _location);
+ Id stackElement(int _stackHeight, langutil::SourceLocation const& _location);
/// @returns the stackElement relative to the current stack height.
- Id relativeStackElement(int _stackOffset, SourceLocation const& _location = SourceLocation());
+ Id relativeStackElement(int _stackOffset, langutil::SourceLocation const& _location = {});
/// @returns its set of tags if the given expression class is a known tag union; returns a set
/// containing the tag if it is a PushTag expression and the empty set otherwise.
@@ -142,22 +147,22 @@ private:
/// Assigns a new equivalence class to the next sequence number of the given stack element.
void setStackElement(int _stackHeight, Id _class);
/// Swaps the given stack elements in their next sequence number.
- void swapStackElements(int _stackHeightA, int _stackHeightB, SourceLocation const& _location);
+ void swapStackElements(int _stackHeightA, int _stackHeightB, langutil::SourceLocation const& _location);
/// Increments the sequence number, deletes all storage information that might be overwritten
/// and stores the new value at the given slot.
/// @returns the store operation, which might be invalid if storage was not modified
- StoreOperation storeInStorage(Id _slot, Id _value, SourceLocation const& _location);
+ StoreOperation storeInStorage(Id _slot, Id _value, langutil::SourceLocation const& _location);
/// Retrieves the current value at the given slot in storage or creates a new special sload class.
- Id loadFromStorage(Id _slot, SourceLocation const& _location);
+ Id loadFromStorage(Id _slot, langutil::SourceLocation const& _location);
/// Increments the sequence number, deletes all memory information that might be overwritten
/// and stores the new value at the given slot.
/// @returns the store operation, which might be invalid if memory was not modified
- StoreOperation storeInMemory(Id _slot, Id _value, SourceLocation const& _location);
+ StoreOperation storeInMemory(Id _slot, Id _value, langutil::SourceLocation const& _location);
/// Retrieves the current value at the given slot in memory or creates a new special mload class.
- Id loadFromMemory(Id _slot, SourceLocation const& _location);
+ Id loadFromMemory(Id _slot, langutil::SourceLocation const& _location);
/// Finds or creates a new expression that applies the Keccak-256 hash function to the contents in memory.
- Id applyKeccak256(Id _start, Id _length, SourceLocation const& _location);
+ Id applyKeccak256(Id _start, Id _length, langutil::SourceLocation const& _location);
/// @returns a new or already used Id representing the given set of tags.
Id tagUnion(std::set<u256> _tags);
diff --git a/libevmasm/PathGasMeter.h b/libevmasm/PathGasMeter.h
index fb821684..772df484 100644
--- a/libevmasm/PathGasMeter.h
+++ b/libevmasm/PathGasMeter.h
@@ -23,7 +23,7 @@
#include <libevmasm/GasMeter.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <set>
#include <vector>
diff --git a/libevmasm/SimplificationRules.cpp b/libevmasm/SimplificationRules.cpp
index 120d1787..1dce5f1e 100644
--- a/libevmasm/SimplificationRules.cpp
+++ b/libevmasm/SimplificationRules.cpp
@@ -38,7 +38,7 @@
using namespace std;
using namespace dev;
using namespace dev::eth;
-
+using namespace langutil;
SimplificationRule<Pattern> const* Rules::findFirstMatch(
Expression const& _expr,
diff --git a/libevmasm/SimplificationRules.h b/libevmasm/SimplificationRules.h
index fbe5a2b0..fc45a46c 100644
--- a/libevmasm/SimplificationRules.h
+++ b/libevmasm/SimplificationRules.h
@@ -31,6 +31,11 @@
#include <functional>
#include <vector>
+namespace langutil
+{
+struct SourceLocation;
+}
+
namespace dev
{
namespace eth
@@ -97,7 +102,7 @@ public:
unsigned matchGroup() const { return m_matchGroup; }
bool matches(Expression const& _expr, ExpressionClasses const& _classes) const;
- AssemblyItem toAssemblyItem(SourceLocation const& _location) const;
+ AssemblyItem toAssemblyItem(langutil::SourceLocation const& _location) const;
std::vector<Pattern> arguments() const { return m_arguments; }
/// @returns the id of the matched expression if this pattern is part of a match group.
@@ -135,7 +140,7 @@ struct ExpressionTemplate
{
using Expression = ExpressionClasses::Expression;
using Id = ExpressionClasses::Id;
- explicit ExpressionTemplate(Pattern const& _pattern, SourceLocation const& _location);
+ explicit ExpressionTemplate(Pattern const& _pattern, langutil::SourceLocation const& _location);
std::string toString() const;
bool hasId = false;
/// Id of the matched expression, if available.
diff --git a/liblangutil/CMakeLists.txt b/liblangutil/CMakeLists.txt
new file mode 100644
index 00000000..3d8bd37a
--- /dev/null
+++ b/liblangutil/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Solidity Commons Library (Solidity related sharing bits between libsolidity and libyul)
+set(sources
+ CharStream.cpp
+ ErrorReporter.cpp
+ Exceptions.cpp
+ ParserBase.cpp
+ Scanner.cpp
+ Token.cpp
+)
+
+add_library(langutil ${sources})
+target_link_libraries(langutil PUBLIC devcore)
diff --git a/liblangutil/CharStream.cpp b/liblangutil/CharStream.cpp
new file mode 100644
index 00000000..aee7cb3e
--- /dev/null
+++ b/liblangutil/CharStream.cpp
@@ -0,0 +1,108 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+
+ This file is derived from the file "scanner.cc", which was part of the
+ V8 project. The original copyright header follows:
+
+ Copyright 2006-2012, the V8 project authors. All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**
+ * @author Christian <c@ethdev.com>
+ * @date 2014
+ * Solidity scanner.
+ */
+
+#include <liblangutil/CharStream.h>
+#include <liblangutil/Exceptions.h>
+
+using namespace std;
+using namespace langutil;
+
+char CharStream::advanceAndGet(size_t _chars)
+{
+ if (isPastEndOfInput())
+ return 0;
+ m_position += _chars;
+ if (isPastEndOfInput())
+ return 0;
+ return m_source[m_position];
+}
+
+char CharStream::rollback(size_t _amount)
+{
+ solAssert(m_position >= _amount, "");
+ m_position -= _amount;
+ return get();
+}
+
+string CharStream::lineAtPosition(int _position) const
+{
+ // if _position points to \n, it returns the line before the \n
+ using size_type = string::size_type;
+ size_type searchStart = min<size_type>(m_source.size(), _position);
+ if (searchStart > 0)
+ searchStart--;
+ size_type lineStart = m_source.rfind('\n', searchStart);
+ if (lineStart == string::npos)
+ lineStart = 0;
+ else
+ lineStart++;
+ return m_source.substr(lineStart, min(m_source.find('\n', lineStart),
+ m_source.size()) - lineStart);
+}
+
+tuple<int, int> CharStream::translatePositionToLineColumn(int _position) const
+{
+ using size_type = string::size_type;
+ size_type searchPosition = min<size_type>(m_source.size(), _position);
+ int lineNumber = count(m_source.begin(), m_source.begin() + searchPosition, '\n');
+ size_type lineStart;
+ if (searchPosition == 0)
+ lineStart = 0;
+ else
+ {
+ lineStart = m_source.rfind('\n', searchPosition - 1);
+ lineStart = lineStart == string::npos ? 0 : lineStart + 1;
+ }
+ return tuple<int, int>(lineNumber, searchPosition - lineStart);
+}
+
+
diff --git a/liblangutil/CharStream.h b/liblangutil/CharStream.h
new file mode 100644
index 00000000..72aacacf
--- /dev/null
+++ b/liblangutil/CharStream.h
@@ -0,0 +1,97 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+
+ This file is derived from the file "scanner.h", which was part of the
+ V8 project. The original copyright header follows:
+
+ Copyright 2006-2012, the V8 project authors. All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**
+ * @author Christian <c@ethdev.com>
+ * @date 2014
+ * Solidity scanner.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <string>
+#include <tuple>
+
+namespace langutil
+{
+
+/**
+ * Bidirectional stream of characters.
+ *
+ * This CharStream is used by lexical analyzers as the source.
+ */
+class CharStream
+{
+public:
+ CharStream(): m_position(0) {}
+ explicit CharStream(std::string const& _source): m_source(_source), m_position(0) {}
+
+ int position() const { return m_position; }
+ bool isPastEndOfInput(size_t _charsForward = 0) const { return (m_position + _charsForward) >= m_source.size(); }
+
+ char get(size_t _charsForward = 0) const { return m_source[m_position + _charsForward]; }
+ char advanceAndGet(size_t _chars = 1);
+ char rollback(size_t _amount);
+
+ void reset() { m_position = 0; }
+
+ std::string const& source() const { return m_source; }
+
+ ///@{
+ ///@name Error printing helper functions
+ /// Functions that help pretty-printing parse errors
+ /// Do only use in error cases, they are quite expensive.
+ std::string lineAtPosition(int _position) const;
+ std::tuple<int, int> translatePositionToLineColumn(int _position) const;
+ ///@}
+
+private:
+ std::string m_source;
+ size_t m_position;
+};
+
+}
diff --git a/libsolidity/interface/EVMVersion.h b/liblangutil/EVMVersion.h
index 657727ac..657727ac 100644
--- a/libsolidity/interface/EVMVersion.h
+++ b/liblangutil/EVMVersion.h
diff --git a/libsolidity/interface/ErrorReporter.cpp b/liblangutil/ErrorReporter.cpp
index 368e25e0..5b6e0072 100644
--- a/libsolidity/interface/ErrorReporter.cpp
+++ b/liblangutil/ErrorReporter.cpp
@@ -20,13 +20,13 @@
* Error helper class.
*/
-#include <libsolidity/interface/ErrorReporter.h>
-#include <libsolidity/ast/AST.h>
+#include <liblangutil/ErrorReporter.h>
+#include <liblangutil/SourceLocation.h>
#include <memory>
using namespace std;
using namespace dev;
-using namespace dev::solidity;
+using namespace langutil;
ErrorReporter& ErrorReporter::operator=(ErrorReporter const& _errorReporter)
{
diff --git a/libsolidity/interface/ErrorReporter.h b/liblangutil/ErrorReporter.h
index fd53587a..d90e652e 100644
--- a/libsolidity/interface/ErrorReporter.h
+++ b/liblangutil/ErrorReporter.h
@@ -22,15 +22,11 @@
#pragma once
-#include <libsolidity/interface/Exceptions.h>
-#include <libevmasm/SourceLocation.h>
+#include <liblangutil/Exceptions.h>
+#include <liblangutil/SourceLocation.h>
-namespace dev
+namespace langutil
{
-namespace solidity
-{
-
-class ASTNode;
class ErrorReporter
{
@@ -120,7 +116,5 @@ private:
const unsigned c_maxErrorsAllowed = 256;
};
-
-}
}
diff --git a/libsolidity/interface/Exceptions.cpp b/liblangutil/Exceptions.cpp
index ecadd0b7..346313d5 100644
--- a/libsolidity/interface/Exceptions.cpp
+++ b/liblangutil/Exceptions.cpp
@@ -20,11 +20,11 @@
* Solidity exception hierarchy.
*/
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
using namespace std;
using namespace dev;
-using namespace dev::solidity;
+using namespace langutil;
Error::Error(Type _type, SourceLocation const& _location, string const& _description):
m_type(_type)
diff --git a/libsolidity/interface/Exceptions.h b/liblangutil/Exceptions.h
index 629b8f3f..5ad31ab2 100644
--- a/libsolidity/interface/Exceptions.h
+++ b/liblangutil/Exceptions.h
@@ -24,33 +24,33 @@
#include <string>
#include <utility>
+#include <vector>
+#include <memory>
#include <libdevcore/Exceptions.h>
#include <libdevcore/Assertions.h>
-#include <libevmasm/SourceLocation.h>
+#include <liblangutil/SourceLocation.h>
-namespace dev
-{
-namespace solidity
+namespace langutil
{
class Error;
using ErrorList = std::vector<std::shared_ptr<Error const>>;
-struct CompilerError: virtual Exception {};
-struct InternalCompilerError: virtual Exception {};
-struct FatalError: virtual Exception {};
-struct UnimplementedFeatureError: virtual Exception{};
+struct CompilerError: virtual dev::Exception {};
+struct InternalCompilerError: virtual dev::Exception {};
+struct FatalError: virtual dev::Exception {};
+struct UnimplementedFeatureError: virtual dev::Exception {};
/// Assertion that throws an InternalCompilerError containing the given description if it is not met.
#define solAssert(CONDITION, DESCRIPTION) \
- assertThrow(CONDITION, ::dev::solidity::InternalCompilerError, DESCRIPTION)
+ assertThrow(CONDITION, ::langutil::InternalCompilerError, DESCRIPTION)
#define solUnimplementedAssert(CONDITION, DESCRIPTION) \
- assertThrow(CONDITION, ::dev::solidity::UnimplementedFeatureError, DESCRIPTION)
+ assertThrow(CONDITION, ::langutil::UnimplementedFeatureError, DESCRIPTION)
#define solUnimplemented(DESCRIPTION) \
solUnimplementedAssert(false, DESCRIPTION)
-class Error: virtual public Exception
+class Error: virtual public dev::Exception
{
public:
enum class Type
@@ -98,7 +98,6 @@ private:
std::string m_typeName;
};
-
using errorSourceLocationInfo = std::pair<std::string, SourceLocation>;
class SecondarySourceLocation
@@ -109,6 +108,7 @@ public:
infos.push_back(std::make_pair(_errMsg, _sourceLocation));
return *this;
}
+
/// Limits the number of secondary source locations to 32 and appends a notice to the
/// error message.
void limitSize(std::string& _message)
@@ -124,9 +124,8 @@ public:
std::vector<errorSourceLocationInfo> infos;
};
-
using errinfo_sourceLocation = boost::error_info<struct tag_sourceLocation, SourceLocation>;
using errinfo_secondarySourceLocation = boost::error_info<struct tag_secondarySourceLocation, SecondarySourceLocation>;
-}
+
}
diff --git a/libsolidity/parsing/ParserBase.cpp b/liblangutil/ParserBase.cpp
index 1d4cb1e2..8156f9b9 100644
--- a/libsolidity/parsing/ParserBase.cpp
+++ b/liblangutil/ParserBase.cpp
@@ -20,13 +20,12 @@
* Solidity parser shared functionality.
*/
-#include <libsolidity/parsing/ParserBase.h>
-#include <libsolidity/parsing/Scanner.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ParserBase.h>
+#include <liblangutil/Scanner.h>
+#include <liblangutil/ErrorReporter.h>
using namespace std;
-using namespace dev;
-using namespace dev::solidity;
+using namespace langutil;
std::shared_ptr<string const> const& ParserBase::sourceName() const
{
diff --git a/libsolidity/parsing/ParserBase.h b/liblangutil/ParserBase.h
index e01f37d8..3ecabed5 100644
--- a/libsolidity/parsing/ParserBase.h
+++ b/liblangutil/ParserBase.h
@@ -22,12 +22,11 @@
#pragma once
+#include <liblangutil/Token.h>
#include <memory>
-#include <libsolidity/parsing/Token.h>
+#include <string>
-namespace dev
-{
-namespace solidity
+namespace langutil
{
class ErrorReporter;
@@ -90,4 +89,3 @@ protected:
};
}
-}
diff --git a/libsolidity/parsing/Scanner.cpp b/liblangutil/Scanner.cpp
index e9dad2ad..215171b3 100644
--- a/libsolidity/parsing/Scanner.cpp
+++ b/liblangutil/Scanner.cpp
@@ -50,16 +50,15 @@
* Solidity scanner.
*/
+#include <liblangutil/Exceptions.h>
+#include <liblangutil/Scanner.h>
#include <algorithm>
+#include <ostream>
#include <tuple>
-#include <libsolidity/interface/Exceptions.h>
-#include <libsolidity/parsing/Scanner.h>
using namespace std;
-namespace dev
-{
-namespace solidity
+namespace langutil
{
namespace
@@ -102,7 +101,32 @@ int hexValue(char c)
}
} // end anonymous namespace
+std::string to_string(ScannerError _errorCode)
+{
+ switch (_errorCode)
+ {
+ case ScannerError::NoError: return "No error.";
+ case ScannerError::IllegalToken: return "Invalid token.";
+ case ScannerError::IllegalHexString: return "Expected even number of hex-nibbles within double-quotes.";
+ case ScannerError::IllegalHexDigit: return "Hexadecimal digit missing or invalid.";
+ case ScannerError::IllegalCommentTerminator: return "Expected multi-line comment-terminator.";
+ case ScannerError::IllegalEscapeSequence: return "Invalid escape sequence.";
+ case ScannerError::IllegalStringEndQuote: return "Expected string end-quote.";
+ case ScannerError::IllegalNumberSeparator: return "Invalid use of number separator '_'.";
+ case ScannerError::IllegalExponent: return "Invalid exponent.";
+ case ScannerError::IllegalNumberEnd: return "Identifier-start is not allowed at end of a number.";
+ case ScannerError::OctalNotAllowed: return "Octal numbers not allowed.";
+ default:
+ solAssert(false, "Unhandled case in to_string(ScannerError)");
+ return "";
+ }
+}
+std::ostream& operator<<(std::ostream& os, ScannerError _errorCode)
+{
+ os << to_string(_errorCode);
+ return os;
+}
/// Scoped helper for literal recording. Automatically drops the literal
/// if aborting the scanning before it's complete.
@@ -143,10 +167,10 @@ private:
}; // end of LiteralScope class
-void Scanner::reset(CharStream const& _source, string const& _sourceName)
+void Scanner::reset(CharStream _source, string _sourceName)
{
- m_source = _source;
- m_sourceName = make_shared<string const>(_sourceName);
+ m_source = std::move(_source);
+ m_sourceName = make_shared<string const>(std::move(_sourceName));
reset();
}
@@ -313,7 +337,7 @@ Token Scanner::skipMultiLineComment()
}
}
// Unterminated multi-line comment.
- return Token::Illegal;
+ return setError(ScannerError::IllegalCommentTerminator);
}
Token Scanner::scanMultiLineDocComment()
@@ -364,7 +388,7 @@ Token Scanner::scanMultiLineDocComment()
}
literal.complete();
if (!endFound)
- return Token::Illegal;
+ return setError(ScannerError::IllegalCommentTerminator);
else
return Token::CommentLiteral;
}
@@ -394,7 +418,7 @@ Token Scanner::scanSlash()
{
// doxygen style /** natspec comment
if (!advance()) /* slash star comment before EOS */
- return Token::Illegal;
+ return setError(ScannerError::IllegalCommentTerminator);
else if (m_char == '*')
{
advance(); //consume the last '*' at /**
@@ -412,7 +436,7 @@ Token Scanner::scanSlash()
m_nextSkippedComment.location.end = sourcePos();
m_nextSkippedComment.token = comment;
if (comment == Token::Illegal)
- return Token::Illegal;
+ return Token::Illegal; // error already set
else
return Token::Whitespace;
}
@@ -427,6 +451,7 @@ Token Scanner::scanSlash()
void Scanner::scanToken()
{
+ m_nextToken.error = ScannerError::NoError;
m_nextToken.literal.clear();
m_nextToken.extendedTokenInfo = make_tuple(0, 0);
m_nextSkippedComment.literal.clear();
@@ -612,7 +637,7 @@ void Scanner::scanToken()
if (m_char == '"' || m_char == '\'')
token = scanHexString();
else
- token = Token::IllegalHex;
+ token = setError(ScannerError::IllegalToken);
}
}
else if (isDecimalDigit(m_char))
@@ -622,7 +647,7 @@ void Scanner::scanToken()
else if (isSourcePastEndOfInput())
token = Token::EOS;
else
- token = selectToken(Token::Illegal);
+ token = selectErrorToken(ScannerError::IllegalToken);
break;
}
// Continue scanning for tokens as long as we're just skipping
@@ -715,13 +740,13 @@ Token Scanner::scanString()
if (c == '\\')
{
if (isSourcePastEndOfInput() || !scanEscape())
- return Token::Illegal;
+ return setError(ScannerError::IllegalEscapeSequence);
}
else
addLiteralChar(c);
}
if (m_char != quote)
- return Token::Illegal;
+ return setError(ScannerError::IllegalStringEndQuote);
literal.complete();
advance(); // consume quote
return Token::StringLiteral;
@@ -736,11 +761,14 @@ Token Scanner::scanHexString()
{
char c = m_char;
if (!scanHexByte(c))
- return Token::IllegalHex;
+ // can only return false if hex-byte is incomplete (only one hex digit instead of two)
+ return setError(ScannerError::IllegalHexString);
addLiteralChar(c);
}
+
if (m_char != quote)
- return Token::IllegalHex;
+ return setError(ScannerError::IllegalStringEndQuote);
+
literal.complete();
advance(); // consume quote
return Token::StringLiteral;
@@ -769,7 +797,7 @@ Token Scanner::scanNumber(char _charSeen)
// we have already seen a decimal point of the float
addLiteralChar('.');
if (m_char == '_')
- return Token::Illegal;
+ return setError(ScannerError::IllegalToken);
scanDecimalDigits(); // we know we have at least one digit
}
else
@@ -786,14 +814,14 @@ Token Scanner::scanNumber(char _charSeen)
kind = HEX;
addLiteralCharAndAdvance();
if (!isHexDigit(m_char))
- return Token::Illegal; // we must have at least one hex digit after 'x'
+ return setError(ScannerError::IllegalHexDigit); // we must have at least one hex digit after 'x'
while (isHexDigit(m_char) || m_char == '_') // We keep the underscores for later validation
addLiteralCharAndAdvance();
}
else if (isDecimalDigit(m_char))
// We do not allow octal numbers
- return Token::Illegal;
+ return setError(ScannerError::OctalNotAllowed);
}
// Parse decimal digits and allow trailing fractional part.
if (kind == DECIMAL)
@@ -825,7 +853,7 @@ Token Scanner::scanNumber(char _charSeen)
{
solAssert(kind != HEX, "'e'/'E' must be scanned as part of the hex number");
if (kind != DECIMAL)
- return Token::Illegal;
+ return setError(ScannerError::IllegalExponent);
else if (!m_source.isPastEndOfInput(1) && m_source.get(1) == '_')
{
// Recover from wrongly placed underscore as delimiter in literal with scientific
@@ -840,8 +868,8 @@ Token Scanner::scanNumber(char _charSeen)
addLiteralCharAndAdvance(); // 'e' | 'E'
if (m_char == '+' || m_char == '-')
addLiteralCharAndAdvance();
- if (!isDecimalDigit(m_char))
- return Token::Illegal; // we must have at least one decimal digit after 'e'/'E'
+ if (!isDecimalDigit(m_char)) // we must have at least one decimal digit after 'e'/'E'
+ return setError(ScannerError::IllegalExponent);
scanDecimalDigits();
}
// The source character immediately following a numeric literal must
@@ -849,7 +877,7 @@ Token Scanner::scanNumber(char _charSeen)
// section 7.8.3, page 17 (note that we read only one decimal digit
// if the value is 0).
if (isDecimalDigit(m_char) || isIdentifierStart(m_char))
- return Token::Illegal;
+ return setError(ScannerError::IllegalNumberEnd);
literal.complete();
return Token::Number;
}
@@ -866,55 +894,5 @@ tuple<Token, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
return TokenTraits::fromIdentifierOrKeyword(m_nextToken.literal);
}
-char CharStream::advanceAndGet(size_t _chars)
-{
- if (isPastEndOfInput())
- return 0;
- m_position += _chars;
- if (isPastEndOfInput())
- return 0;
- return m_source[m_position];
-}
-char CharStream::rollback(size_t _amount)
-{
- solAssert(m_position >= _amount, "");
- m_position -= _amount;
- return get();
-}
-
-string CharStream::lineAtPosition(int _position) const
-{
- // if _position points to \n, it returns the line before the \n
- using size_type = string::size_type;
- size_type searchStart = min<size_type>(m_source.size(), _position);
- if (searchStart > 0)
- searchStart--;
- size_type lineStart = m_source.rfind('\n', searchStart);
- if (lineStart == string::npos)
- lineStart = 0;
- else
- lineStart++;
- return m_source.substr(lineStart, min(m_source.find('\n', lineStart),
- m_source.size()) - lineStart);
-}
-
-tuple<int, int> CharStream::translatePositionToLineColumn(int _position) const
-{
- using size_type = string::size_type;
- size_type searchPosition = min<size_type>(m_source.size(), _position);
- int lineNumber = count(m_source.begin(), m_source.begin() + searchPosition, '\n');
- size_type lineStart;
- if (searchPosition == 0)
- lineStart = 0;
- else
- {
- lineStart = m_source.rfind('\n', searchPosition - 1);
- lineStart = lineStart == string::npos ? 0 : lineStart + 1;
- }
- return tuple<int, int>(lineNumber, searchPosition - lineStart);
-}
-
-
-}
}
diff --git a/libsolidity/parsing/Scanner.h b/liblangutil/Scanner.h
index 14eeb66e..d01e71e2 100644
--- a/libsolidity/parsing/Scanner.h
+++ b/liblangutil/Scanner.h
@@ -52,62 +52,50 @@
#pragma once
+#include <liblangutil/Token.h>
+#include <liblangutil/CharStream.h>
+#include <liblangutil/SourceLocation.h>
#include <libdevcore/Common.h>
#include <libdevcore/CommonData.h>
-#include <libevmasm/SourceLocation.h>
-#include <libsolidity/parsing/Token.h>
+#include <iosfwd>
-namespace dev
+namespace langutil
{
-namespace solidity
-{
-
class AstRawString;
class AstValueFactory;
class ParserRecorder;
-class CharStream
+enum class ScannerError
{
-public:
- CharStream(): m_position(0) {}
- explicit CharStream(std::string const& _source): m_source(_source), m_position(0) {}
- int position() const { return m_position; }
- bool isPastEndOfInput(size_t _charsForward = 0) const { return (m_position + _charsForward) >= m_source.size(); }
- char get(size_t _charsForward = 0) const { return m_source[m_position + _charsForward]; }
- char advanceAndGet(size_t _chars = 1);
- char rollback(size_t _amount);
-
- void reset() { m_position = 0; }
-
- std::string const& source() const { return m_source; }
-
- ///@{
- ///@name Error printing helper functions
- /// Functions that help pretty-printing parse errors
- /// Do only use in error cases, they are quite expensive.
- std::string lineAtPosition(int _position) const;
- std::tuple<int, int> translatePositionToLineColumn(int _position) const;
- ///@}
-
-private:
- std::string m_source;
- size_t m_position;
+ NoError,
+
+ IllegalToken,
+ IllegalHexString,
+ IllegalHexDigit,
+ IllegalCommentTerminator,
+ IllegalEscapeSequence,
+ IllegalStringEndQuote,
+ IllegalNumberSeparator,
+ IllegalExponent,
+ IllegalNumberEnd,
+
+ OctalNotAllowed,
};
-
+std::string to_string(ScannerError _errorCode);
+std::ostream& operator<<(std::ostream& os, ScannerError _errorCode);
class Scanner
{
friend class LiteralScope;
public:
-
- explicit Scanner(CharStream const& _source = CharStream(), std::string const& _sourceName = "") { reset(_source, _sourceName); }
+ explicit Scanner(CharStream _source = CharStream(), std::string _sourceName = "") { reset(std::move(_source), std::move(_sourceName)); }
std::string source() const { return m_source.source(); }
/// Resets the scanner as if newly constructed with _source and _sourceName as input.
- void reset(CharStream const& _source, std::string const& _sourceName);
+ void reset(CharStream _source, std::string _sourceName);
/// Resets scanner to the start of input.
void reset();
@@ -133,6 +121,10 @@ public:
SourceLocation currentLocation() const { return m_currentToken.location; }
std::string const& currentLiteral() const { return m_currentToken.literal; }
std::tuple<unsigned, unsigned> const& currentTokenInfo() const { return m_currentToken.extendedTokenInfo; }
+
+ /// Retrieves the last error that occurred during lexical analysis.
+ /// @note If no error occurred, the value is undefined.
+ ScannerError currentError() const noexcept { return m_currentToken.error; }
///@}
///@{
@@ -172,12 +164,19 @@ public:
///@}
private:
+ inline Token setError(ScannerError _error) noexcept
+ {
+ m_nextToken.error = _error;
+ return Token::Illegal;
+ }
+
/// Used for the current and look-ahead token and comments
struct TokenDesc
{
Token token;
SourceLocation location;
std::string literal;
+ ScannerError error = ScannerError::NoError;
std::tuple<unsigned, unsigned> extendedTokenInfo;
};
@@ -192,6 +191,7 @@ private:
bool advance() { m_char = m_source.advanceAndGet(); return !m_source.isPastEndOfInput(); }
void rollback(int _amount) { m_char = m_source.rollback(_amount); }
+ inline Token selectErrorToken(ScannerError _err) { advance(); return setError(_err); }
inline Token selectToken(Token _tok) { advance(); return _tok; }
/// If the next character is _next, advance and return _then, otherwise return _else.
inline Token selectToken(char _next, Token _then, Token _else);
@@ -246,4 +246,3 @@ private:
};
}
-}
diff --git a/libevmasm/SourceLocation.h b/liblangutil/SourceLocation.h
index b42c3aa9..eeb81e94 100644
--- a/libevmasm/SourceLocation.h
+++ b/liblangutil/SourceLocation.h
@@ -22,13 +22,13 @@
#pragma once
+#include <libdevcore/Common.h> // defines noexcept macro for MSVC
#include <memory>
#include <string>
#include <ostream>
#include <tuple>
-#include <libdevcore/Common.h> // defines noexcept macro for MSVC
-namespace dev
+namespace langutil
{
/**
diff --git a/libsolidity/interface/SourceReferenceFormatter.cpp b/liblangutil/SourceReferenceFormatter.cpp
index 865907e2..58a65521 100644
--- a/libsolidity/interface/SourceReferenceFormatter.cpp
+++ b/liblangutil/SourceReferenceFormatter.cpp
@@ -20,16 +20,13 @@
* Formatting functions for errors referencing positions and locations in the source.
*/
-#include <libsolidity/interface/SourceReferenceFormatter.h>
-#include <libsolidity/parsing/Scanner.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/SourceReferenceFormatter.h>
+#include <liblangutil/Scanner.h>
+#include <liblangutil/Exceptions.h>
using namespace std;
-
-namespace dev
-{
-namespace solidity
-{
+using namespace dev;
+using namespace langutil;
void SourceReferenceFormatter::printSourceLocation(SourceLocation const* _location)
{
@@ -102,7 +99,7 @@ void SourceReferenceFormatter::printSourceName(SourceLocation const* _location)
}
void SourceReferenceFormatter::printExceptionInformation(
- Exception const& _exception,
+ dev::Exception const& _exception,
string const& _name
)
{
@@ -130,6 +127,3 @@ void SourceReferenceFormatter::printExceptionInformation(
m_stream << endl;
}
}
-
-}
-}
diff --git a/libsolidity/interface/SourceReferenceFormatter.h b/liblangutil/SourceReferenceFormatter.h
index a32babdc..0ef3ca00 100644
--- a/libsolidity/interface/SourceReferenceFormatter.h
+++ b/liblangutil/SourceReferenceFormatter.h
@@ -25,23 +25,21 @@
#include <ostream>
#include <sstream>
#include <functional>
-#include <libevmasm/SourceLocation.h>
namespace dev
{
-
struct Exception; // forward
+}
-namespace solidity
+namespace langutil
{
-
-class Scanner; // forward
-class CompilerStack; // forward
+struct SourceLocation;
+class Scanner;
class SourceReferenceFormatter
{
public:
- using ScannerFromSourceNameFun = std::function<Scanner const&(std::string const&)>;
+ using ScannerFromSourceNameFun = std::function<langutil::Scanner const&(std::string const&)>;
explicit SourceReferenceFormatter(
std::ostream& _stream,
@@ -52,11 +50,11 @@ public:
{}
/// Prints source location if it is given.
- void printSourceLocation(SourceLocation const* _location);
- void printExceptionInformation(Exception const& _exception, std::string const& _name);
+ void printSourceLocation(langutil::SourceLocation const* _location);
+ void printExceptionInformation(dev::Exception const& _exception, std::string const& _name);
static std::string formatExceptionInformation(
- Exception const& _exception,
+ dev::Exception const& _exception,
std::string const& _name,
ScannerFromSourceNameFun const& _scannerFromSourceName
)
@@ -69,11 +67,10 @@ public:
}
private:
/// Prints source name if location is given.
- void printSourceName(SourceLocation const* _location);
+ void printSourceName(langutil::SourceLocation const* _location);
std::ostream& m_stream;
ScannerFromSourceNameFun m_scannerFromSourceName;
};
}
-}
diff --git a/libsolidity/parsing/Token.cpp b/liblangutil/Token.cpp
index dccd9037..cbfd4a8c 100644
--- a/libsolidity/parsing/Token.cpp
+++ b/liblangutil/Token.cpp
@@ -40,15 +40,13 @@
// You should have received a copy of the GNU General Public License
// along with solidity. If not, see <http://www.gnu.org/licenses/>.
-#include <map>
-#include <libsolidity/parsing/Token.h>
+#include <liblangutil/Token.h>
#include <boost/range/iterator_range.hpp>
+#include <map>
using namespace std;
-namespace dev
-{
-namespace solidity
+namespace langutil
{
void ElementaryTypeNameToken::assertDetails(Token _baseType, unsigned const& _first, unsigned const& _second)
@@ -204,4 +202,3 @@ tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(string const& _
}
}
-}
diff --git a/liblangutil/Token.h b/liblangutil/Token.h
new file mode 100644
index 00000000..f832fdf7
--- /dev/null
+++ b/liblangutil/Token.h
@@ -0,0 +1,376 @@
+// Copyright 2006-2012, the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Modifications as part of solidity under the following license:
+//
+// 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 <http://www.gnu.org/licenses/>.
+
+#pragma once
+
+#include <libdevcore/Common.h>
+#include <liblangutil/Exceptions.h>
+#include <liblangutil/UndefMacros.h>
+
+#include <iosfwd>
+#include <string>
+#include <tuple>
+
+namespace langutil
+{
+
+// TOKEN_LIST takes a list of 3 macros M, all of which satisfy the
+// same signature M(name, string, precedence), where name is the
+// symbolic token name, string is the corresponding syntactic symbol
+// (or nullptr, for literals), and precedence is the precedence (or 0).
+// The parameters are invoked for token categories as follows:
+//
+// T: Non-keyword tokens
+// K: Keyword tokens
+
+// IGNORE_TOKEN is a convenience macro that can be supplied as
+// an argument (at any position) for a TOKEN_LIST call. It does
+// nothing with tokens belonging to the respective category.
+
+#define IGNORE_TOKEN(name, string, precedence)
+
+#define TOKEN_LIST(T, K) \
+ /* End of source indicator. */ \
+ T(EOS, "EOS", 0) \
+ \
+ /* Punctuators (ECMA-262, section 7.7, page 15). */ \
+ T(LParen, "(", 0) \
+ T(RParen, ")", 0) \
+ T(LBrack, "[", 0) \
+ T(RBrack, "]", 0) \
+ T(LBrace, "{", 0) \
+ T(RBrace, "}", 0) \
+ T(Colon, ":", 0) \
+ T(Semicolon, ";", 0) \
+ T(Period, ".", 0) \
+ T(Conditional, "?", 3) \
+ T(Arrow, "=>", 0) \
+ \
+ /* Assignment operators. */ \
+ /* IsAssignmentOp() relies on this block of enum values being */ \
+ /* contiguous and sorted in the same order!*/ \
+ T(Assign, "=", 2) \
+ /* The following have to be in exactly the same order as the simple binary operators*/ \
+ T(AssignBitOr, "|=", 2) \
+ T(AssignBitXor, "^=", 2) \
+ T(AssignBitAnd, "&=", 2) \
+ T(AssignShl, "<<=", 2) \
+ T(AssignSar, ">>=", 2) \
+ T(AssignShr, ">>>=", 2) \
+ T(AssignAdd, "+=", 2) \
+ T(AssignSub, "-=", 2) \
+ T(AssignMul, "*=", 2) \
+ T(AssignDiv, "/=", 2) \
+ T(AssignMod, "%=", 2) \
+ \
+ /* Binary operators sorted by precedence. */ \
+ /* IsBinaryOp() relies on this block of enum values */ \
+ /* being contiguous and sorted in the same order! */ \
+ T(Comma, ",", 1) \
+ T(Or, "||", 4) \
+ T(And, "&&", 5) \
+ T(BitOr, "|", 8) \
+ T(BitXor, "^", 9) \
+ T(BitAnd, "&", 10) \
+ T(SHL, "<<", 11) \
+ T(SAR, ">>", 11) \
+ T(SHR, ">>>", 11) \
+ T(Add, "+", 12) \
+ T(Sub, "-", 12) \
+ T(Mul, "*", 13) \
+ T(Div, "/", 13) \
+ T(Mod, "%", 13) \
+ T(Exp, "**", 14) \
+ \
+ /* Compare operators sorted by precedence. */ \
+ /* IsCompareOp() relies on this block of enum values */ \
+ /* being contiguous and sorted in the same order! */ \
+ T(Equal, "==", 6) \
+ T(NotEqual, "!=", 6) \
+ T(LessThan, "<", 7) \
+ T(GreaterThan, ">", 7) \
+ T(LessThanOrEqual, "<=", 7) \
+ T(GreaterThanOrEqual, ">=", 7) \
+ \
+ /* Unary operators. */ \
+ /* IsUnaryOp() relies on this block of enum values */ \
+ /* being contiguous and sorted in the same order! */ \
+ T(Not, "!", 0) \
+ T(BitNot, "~", 0) \
+ T(Inc, "++", 0) \
+ T(Dec, "--", 0) \
+ K(Delete, "delete", 0) \
+ \
+ /* Keywords */ \
+ K(Anonymous, "anonymous", 0) \
+ K(As, "as", 0) \
+ K(Assembly, "assembly", 0) \
+ K(Break, "break", 0) \
+ K(Constant, "constant", 0) \
+ K(Constructor, "constructor", 0) \
+ K(Continue, "continue", 0) \
+ K(Contract, "contract", 0) \
+ K(Do, "do", 0) \
+ K(Else, "else", 0) \
+ K(Enum, "enum", 0) \
+ K(Emit, "emit", 0) \
+ K(Event, "event", 0) \
+ K(External, "external", 0) \
+ K(For, "for", 0) \
+ K(Function, "function", 0) \
+ K(Hex, "hex", 0) \
+ K(If, "if", 0) \
+ K(Indexed, "indexed", 0) \
+ K(Interface, "interface", 0) \
+ K(Internal, "internal", 0) \
+ K(Import, "import", 0) \
+ K(Is, "is", 0) \
+ K(Library, "library", 0) \
+ K(Mapping, "mapping", 0) \
+ K(Memory, "memory", 0) \
+ K(Modifier, "modifier", 0) \
+ K(New, "new", 0) \
+ K(Payable, "payable", 0) \
+ K(Public, "public", 0) \
+ K(Pragma, "pragma", 0) \
+ K(Private, "private", 0) \
+ K(Pure, "pure", 0) \
+ K(Return, "return", 0) \
+ K(Returns, "returns", 0) \
+ K(Storage, "storage", 0) \
+ K(CallData, "calldata", 0) \
+ K(Struct, "struct", 0) \
+ K(Throw, "throw", 0) \
+ K(Using, "using", 0) \
+ K(Var, "var", 0) \
+ K(View, "view", 0) \
+ K(While, "while", 0) \
+ \
+ /* Ether subdenominations */ \
+ K(SubWei, "wei", 0) \
+ K(SubSzabo, "szabo", 0) \
+ K(SubFinney, "finney", 0) \
+ K(SubEther, "ether", 0) \
+ K(SubSecond, "seconds", 0) \
+ K(SubMinute, "minutes", 0) \
+ K(SubHour, "hours", 0) \
+ K(SubDay, "days", 0) \
+ K(SubWeek, "weeks", 0) \
+ K(SubYear, "years", 0) \
+ /* type keywords*/ \
+ K(Int, "int", 0) \
+ K(UInt, "uint", 0) \
+ K(Bytes, "bytes", 0) \
+ K(Byte, "byte", 0) \
+ K(String, "string", 0) \
+ K(Address, "address", 0) \
+ K(Bool, "bool", 0) \
+ K(Fixed, "fixed", 0) \
+ K(UFixed, "ufixed", 0) \
+ T(IntM, "intM", 0) \
+ T(UIntM, "uintM", 0) \
+ T(BytesM, "bytesM", 0) \
+ T(FixedMxN, "fixedMxN", 0) \
+ T(UFixedMxN, "ufixedMxN", 0) \
+ T(TypesEnd, nullptr, 0) /* used as type enum end marker */ \
+ \
+ /* Literals */ \
+ K(TrueLiteral, "true", 0) \
+ K(FalseLiteral, "false", 0) \
+ T(Number, nullptr, 0) \
+ T(StringLiteral, nullptr, 0) \
+ T(CommentLiteral, nullptr, 0) \
+ \
+ /* Identifiers (not keywords or future reserved words). */ \
+ T(Identifier, nullptr, 0) \
+ \
+ /* Keywords reserved for future use. */ \
+ K(Abstract, "abstract", 0) \
+ K(After, "after", 0) \
+ K(Alias, "alias", 0) \
+ K(Apply, "apply", 0) \
+ K(Auto, "auto", 0) \
+ K(Case, "case", 0) \
+ K(Catch, "catch", 0) \
+ K(CopyOf, "copyof", 0) \
+ K(Default, "default", 0) \
+ K(Define, "define", 0) \
+ K(Final, "final", 0) \
+ K(Immutable, "immutable", 0) \
+ K(Implements, "implements", 0) \
+ K(In, "in", 0) \
+ K(Inline, "inline", 0) \
+ K(Let, "let", 0) \
+ K(Macro, "macro", 0) \
+ K(Match, "match", 0) \
+ K(Mutable, "mutable", 0) \
+ K(NullLiteral, "null", 0) \
+ K(Of, "of", 0) \
+ K(Override, "override", 0) \
+ K(Partial, "partial", 0) \
+ K(Promise, "promise", 0) \
+ K(Reference, "reference", 0) \
+ K(Relocatable, "relocatable", 0) \
+ K(Sealed, "sealed", 0) \
+ K(Sizeof, "sizeof", 0) \
+ K(Static, "static", 0) \
+ K(Supports, "supports", 0) \
+ K(Switch, "switch", 0) \
+ K(Try, "try", 0) \
+ K(Type, "type", 0) \
+ K(Typedef, "typedef", 0) \
+ K(TypeOf, "typeof", 0) \
+ K(Unchecked, "unchecked", 0) \
+ \
+ /* Illegal token - not able to scan. */ \
+ T(Illegal, "ILLEGAL", 0) \
+ \
+ /* Scanner-internal use only. */ \
+ T(Whitespace, nullptr, 0)
+
+// All token values.
+// attention! msvc issue:
+// http://stackoverflow.com/questions/9567868/compile-errors-after-adding-v8-to-my-project-c2143-c2059
+// @todo: avoid TOKEN_LIST macro
+enum class Token : unsigned int {
+#define T(name, string, precedence) name,
+ TOKEN_LIST(T, T)
+ NUM_TOKENS
+#undef T
+};
+
+namespace TokenTraits
+{
+ constexpr size_t count() { return static_cast<size_t>(Token::NUM_TOKENS); }
+
+ // Predicates
+ constexpr bool isElementaryTypeName(Token tok) { return Token::Int <= tok && tok < Token::TypesEnd; }
+ constexpr bool isAssignmentOp(Token tok) { return Token::Assign <= tok && tok <= Token::AssignMod; }
+ constexpr bool isBinaryOp(Token op) { return Token::Comma <= op && op <= Token::Exp; }
+ constexpr bool isCommutativeOp(Token op) { return op == Token::BitOr || op == Token::BitXor || op == Token::BitAnd ||
+ op == Token::Add || op == Token::Mul || op == Token::Equal || op == Token::NotEqual; }
+ constexpr bool isArithmeticOp(Token op) { return Token::Add <= op && op <= Token::Exp; }
+ constexpr bool isCompareOp(Token op) { return Token::Equal <= op && op <= Token::GreaterThanOrEqual; }
+
+ constexpr bool isBitOp(Token op) { return (Token::BitOr <= op && op <= Token::BitAnd) || op == Token::BitNot; }
+ constexpr bool isBooleanOp(Token op) { return (Token::Or <= op && op <= Token::And) || op == Token::Not; }
+ constexpr bool isUnaryOp(Token op) { return (Token::Not <= op && op <= Token::Delete) || op == Token::Add || op == Token::Sub; }
+ constexpr bool isCountOp(Token op) { return op == Token::Inc || op == Token::Dec; }
+ constexpr bool isShiftOp(Token op) { return (Token::SHL <= op) && (op <= Token::SHR); }
+ constexpr bool isVariableVisibilitySpecifier(Token op) { return op == Token::Public || op == Token::Private || op == Token::Internal; }
+ constexpr bool isVisibilitySpecifier(Token op) { return isVariableVisibilitySpecifier(op) || op == Token::External; }
+ constexpr bool isLocationSpecifier(Token op) { return op == Token::Memory || op == Token::Storage || op == Token::CallData; }
+
+ constexpr bool isStateMutabilitySpecifier(Token op, bool _allowConstant = true)
+ {
+ return (op == Token::Constant && _allowConstant)
+ || op == Token::Pure || op == Token::View || op == Token::Payable;
+ }
+
+ constexpr bool isEtherSubdenomination(Token op) { return op == Token::SubWei || op == Token::SubSzabo || op == Token::SubFinney || op == Token::SubEther; }
+ constexpr bool isTimeSubdenomination(Token op) { return op == Token::SubSecond || op == Token::SubMinute || op == Token::SubHour || op == Token::SubDay || op == Token::SubWeek || op == Token::SubYear; }
+ constexpr bool isReservedKeyword(Token op) { return (Token::Abstract <= op && op <= Token::Unchecked); }
+
+ inline Token AssignmentToBinaryOp(Token op)
+ {
+ solAssert(isAssignmentOp(op) && op != Token::Assign, "");
+ return static_cast<Token>(static_cast<int>(op) + (static_cast<int>(Token::BitOr) - static_cast<int>(Token::AssignBitOr)));
+ }
+
+ // @returns the precedence > 0 for binary and compare
+ // operators; returns 0 otherwise.
+ int precedence(Token tok);
+
+ std::tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(std::string const& _literal);
+
+ // @returns a string corresponding to the C++ token name
+ // (e.g. "LT" for the token LT).
+ char const* name(Token tok);
+
+ // @returns a string corresponding to the JS token string
+ // (.e., "<" for the token LT) or nullptr if the token doesn't
+ // have a (unique) string (e.g. an IDENTIFIER).
+ char const* toString(Token tok);
+
+ std::string friendlyName(Token tok);
+}
+
+inline std::ostream& operator<<(std::ostream& os, Token token)
+{
+ os << TokenTraits::friendlyName(token);
+ return os;
+}
+
+class ElementaryTypeNameToken
+{
+public:
+ ElementaryTypeNameToken(Token _token, unsigned const& _firstNumber, unsigned const& _secondNumber)
+ {
+ assertDetails(_token, _firstNumber, _secondNumber);
+ }
+
+ unsigned int firstNumber() const { return m_firstNumber; }
+ unsigned int secondNumber() const { return m_secondNumber; }
+ Token token() const { return m_token; }
+
+ ///if tokValue is set to true, then returns the actual token type name, otherwise, returns full type
+ std::string toString(bool const& tokenValue = false) const
+ {
+ std::string name = TokenTraits::toString(m_token);
+ if (tokenValue || (firstNumber() == 0 && secondNumber() == 0))
+ return name;
+ solAssert(name.size() >= 3, "Token name size should be greater than 3. Should not reach here.");
+ if (m_token == Token::FixedMxN || m_token == Token::UFixedMxN)
+ return name.substr(0, name.size() - 3) + std::to_string(m_firstNumber) + "x" + std::to_string(m_secondNumber);
+ else
+ return name.substr(0, name.size() - 1) + std::to_string(m_firstNumber);
+ }
+
+private:
+ Token m_token;
+ unsigned int m_firstNumber;
+ unsigned int m_secondNumber;
+ /// throws if type is not properly sized
+ void assertDetails(Token _baseType, unsigned const& _first, unsigned const& _second);
+};
+
+}
diff --git a/libsolidity/parsing/UndefMacros.h b/liblangutil/UndefMacros.h
index d96e242e..d96e242e 100644
--- a/libsolidity/parsing/UndefMacros.h
+++ b/liblangutil/UndefMacros.h
diff --git a/liblll/CMakeLists.txt b/liblll/CMakeLists.txt
index 4cdc073a..9566c62f 100644
--- a/liblll/CMakeLists.txt
+++ b/liblll/CMakeLists.txt
@@ -1,5 +1,9 @@
-file(GLOB sources "*.cpp")
-file(GLOB headers "*.h")
+set(sources
+ CodeFragment.cpp
+ Compiler.cpp
+ CompilerState.cpp
+ Parser.cpp
+)
-add_library(lll ${sources} ${headers})
+add_library(lll ${sources})
target_link_libraries(lll PUBLIC evmasm devcore)
diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp
index f37cb8b9..b32f14e9 100644
--- a/liblll/CodeFragment.cpp
+++ b/liblll/CodeFragment.cpp
@@ -259,6 +259,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
}
else if (us == "SET")
{
+ // TODO: move this to be a stack variable (and not a memory variable)
if (_t.size() != 3)
error<IncorrectParameterCount>(us);
int c = 0;
@@ -268,6 +269,15 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
m_asm.append((u256)varAddress(firstAsString(), true));
m_asm.append(Instruction::MSTORE);
}
+ else if (us == "UNSET")
+ {
+ // TODO: this doesn't actually free up anything, since it is a memory variable (see "SET")
+ if (_t.size() != 2)
+ error<IncorrectParameterCount>();
+ auto it = _s.vars.find(firstAsString());
+ if (it != _s.vars.end())
+ _s.vars.erase(it);
+ }
else if (us == "GET")
{
if (_t.size() != 2)
@@ -275,6 +285,35 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
m_asm.append((u256)varAddress(firstAsString()));
m_asm.append(Instruction::MLOAD);
}
+ else if (us == "WITH")
+ {
+ if (_t.size() != 4)
+ error<IncorrectParameterCount>();
+ string key = firstAsString();
+ if (_s.vars.find(key) != _s.vars.end())
+ error<InvalidName>(string("Symbol already used: ") + key);
+
+ // Create variable
+ // TODO: move this to be a stack variable (and not a memory variable)
+ size_t c = 0;
+ for (auto const& i: _t)
+ if (c++ == 2)
+ m_asm.append(CodeFragment(i, _s, m_readFile, false).m_asm);
+ m_asm.append((u256)varAddress(key, true));
+ m_asm.append(Instruction::MSTORE);
+
+ // Insert sub with variable access, but new state
+ CompilerState ns = _s;
+ c = 0;
+ for (auto const& i: _t)
+ if (c++ == 3)
+ m_asm.append(CodeFragment(i, _s, m_readFile, false).m_asm);
+
+ // Remove variable
+ auto it = _s.vars.find(key);
+ if (it != _s.vars.end())
+ _s.vars.erase(it);
+ }
else if (us == "REF")
m_asm.append((u256)varAddress(firstAsString()));
else if (us == "DEF")
diff --git a/liblll/Compiler.h b/liblll/Compiler.h
index 1ff7d5f8..93235cdd 100644
--- a/liblll/Compiler.h
+++ b/liblll/Compiler.h
@@ -23,7 +23,7 @@
#include <libdevcore/Common.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <string>
#include <vector>
diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt
index 136d39b1..40996aba 100644
--- a/libsolidity/CMakeLists.txt
+++ b/libsolidity/CMakeLists.txt
@@ -1,14 +1,60 @@
# Until we have a clear separation, libyul has to be included here
-file(GLOB_RECURSE sources "*.cpp" "../libyul/*.cpp")
-file(GLOB_RECURSE headers "*.h" "../libyul/*.h")
+set(sources
+ analysis/ConstantEvaluator.cpp
+ analysis/ControlFlowAnalyzer.cpp
+ analysis/ControlFlowBuilder.cpp
+ analysis/ControlFlowGraph.cpp
+ analysis/DeclarationContainer.cpp
+ analysis/DocStringAnalyser.cpp
+ analysis/GlobalContext.cpp
+ analysis/NameAndTypeResolver.cpp
+ analysis/PostTypeChecker.cpp
+ analysis/ReferencesResolver.cpp
+ analysis/SemVerHandler.cpp
+ analysis/StaticAnalyzer.cpp
+ analysis/SyntaxChecker.cpp
+ analysis/TypeChecker.cpp
+ analysis/ViewPureChecker.cpp
+ ast/AST.cpp
+ ast/ASTAnnotations.cpp
+ ast/ASTJsonConverter.cpp
+ ast/ASTPrinter.cpp
+ ast/Types.cpp
+ codegen/ABIFunctions.cpp
+ codegen/ArrayUtils.cpp
+ codegen/Compiler.cpp
+ codegen/CompilerContext.cpp
+ codegen/CompilerUtils.cpp
+ codegen/ContractCompiler.cpp
+ codegen/ExpressionCompiler.cpp
+ codegen/LValue.cpp
+ formal/SMTChecker.cpp
+ formal/SMTLib2Interface.cpp
+ formal/SMTPortfolio.cpp
+ formal/SSAVariable.cpp
+ formal/SymbolicTypes.cpp
+ formal/SymbolicVariables.cpp
+ formal/VariableUsage.cpp
+ interface/ABI.cpp
+ interface/AssemblyStack.cpp
+ interface/CompilerStack.cpp
+ interface/GasEstimator.cpp
+ interface/Natspec.cpp
+ interface/SourceReferenceFormatter.cpp
+ interface/StandardCompiler.cpp
+ interface/Version.cpp
+ parsing/DocStringParser.cpp
+ parsing/Parser.cpp
+)
find_package(Z3 QUIET)
if (${Z3_FOUND})
include_directories(${Z3_INCLUDE_DIR})
add_definitions(-DHAVE_Z3)
message("Z3 SMT solver found. This enables optional SMT checking with Z3.")
+ set(z3_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/formal/Z3Interface.cpp")
else()
- list(REMOVE_ITEM sources "${CMAKE_CURRENT_SOURCE_DIR}/formal/Z3Interface.cpp")
+ set(z3_SRCS)
endif()
find_package(CVC4 QUIET)
@@ -16,8 +62,9 @@ if (${CVC4_FOUND})
include_directories(${CVC4_INCLUDE_DIR})
add_definitions(-DHAVE_CVC4)
message("CVC4 SMT solver found. This enables optional SMT checking with CVC4.")
+ set(cvc4_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/formal/CVC4Interface.cpp")
else()
- list(REMOVE_ITEM sources "${CMAKE_CURRENT_SOURCE_DIR}/formal/CVC4Interface.cpp")
+ set(cvc4_SRCS)
endif()
if (NOT (${Z3_FOUND} OR ${CVC4_FOUND}))
@@ -25,8 +72,8 @@ if (NOT (${Z3_FOUND} OR ${CVC4_FOUND}))
\nPlease install Z3 or CVC4 or remove the option disabling them (USE_Z3, USE_CVC4).")
endif()
-add_library(solidity ${sources} ${headers})
-target_link_libraries(solidity PUBLIC evmasm devcore ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY})
+add_library(solidity ${sources} ${z3_SRCS} ${cvc4_SRCS})
+target_link_libraries(solidity PUBLIC yul evmasm langutil devcore ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY})
if (${Z3_FOUND})
target_link_libraries(solidity PUBLIC ${Z3_LIBRARY})
diff --git a/libsolidity/analysis/ConstantEvaluator.cpp b/libsolidity/analysis/ConstantEvaluator.cpp
index f9b00927..9d041ce5 100644
--- a/libsolidity/analysis/ConstantEvaluator.cpp
+++ b/libsolidity/analysis/ConstantEvaluator.cpp
@@ -22,7 +22,7 @@
#include <libsolidity/analysis/ConstantEvaluator.h>
#include <libsolidity/ast/AST.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
using namespace std;
using namespace dev;
diff --git a/libsolidity/analysis/ConstantEvaluator.h b/libsolidity/analysis/ConstantEvaluator.h
index ac3a24a1..23ca3628 100644
--- a/libsolidity/analysis/ConstantEvaluator.h
+++ b/libsolidity/analysis/ConstantEvaluator.h
@@ -24,12 +24,16 @@
#include <libsolidity/ast/ASTVisitor.h>
+namespace langutil
+{
+class ErrorReporter;
+}
+
namespace dev
{
namespace solidity
{
-class ErrorReporter;
class TypeChecker;
/**
@@ -39,7 +43,7 @@ class ConstantEvaluator: private ASTConstVisitor
{
public:
ConstantEvaluator(
- ErrorReporter& _errorReporter,
+ langutil::ErrorReporter& _errorReporter,
size_t _newDepth = 0,
std::shared_ptr<std::map<ASTNode const*, TypePointer>> _types = std::make_shared<std::map<ASTNode const*, TypePointer>>()
):
@@ -61,7 +65,7 @@ private:
void setType(ASTNode const& _node, TypePointer const& _type);
TypePointer type(ASTNode const& _node);
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
/// Current recursion depth.
size_t m_depth = 0;
std::shared_ptr<std::map<ASTNode const*, TypePointer>> m_types;
diff --git a/libsolidity/analysis/ControlFlowAnalyzer.cpp b/libsolidity/analysis/ControlFlowAnalyzer.cpp
index 8a608552..fe58f0aa 100644
--- a/libsolidity/analysis/ControlFlowAnalyzer.cpp
+++ b/libsolidity/analysis/ControlFlowAnalyzer.cpp
@@ -16,8 +16,10 @@
*/
#include <libsolidity/analysis/ControlFlowAnalyzer.h>
+#include <liblangutil/SourceLocation.h>
using namespace std;
+using namespace langutil;
using namespace dev::solidity;
bool ControlFlowAnalyzer::analyze(ASTNode const& _astRoot)
diff --git a/libsolidity/analysis/ControlFlowAnalyzer.h b/libsolidity/analysis/ControlFlowAnalyzer.h
index 43e13fb6..411d57ff 100644
--- a/libsolidity/analysis/ControlFlowAnalyzer.h
+++ b/libsolidity/analysis/ControlFlowAnalyzer.h
@@ -29,12 +29,12 @@ namespace solidity
class ControlFlowAnalyzer: private ASTConstVisitor
{
public:
- explicit ControlFlowAnalyzer(CFG const& _cfg, ErrorReporter& _errorReporter):
+ explicit ControlFlowAnalyzer(CFG const& _cfg, langutil::ErrorReporter& _errorReporter):
m_cfg(_cfg), m_errorReporter(_errorReporter) {}
bool analyze(ASTNode const& _astRoot);
- virtual bool visit(FunctionDefinition const& _function) override;
+ bool visit(FunctionDefinition const& _function) override;
private:
static std::set<VariableDeclaration const*> variablesAssignedInNode(CFGNode const *node);
@@ -45,7 +45,7 @@ private:
) const;
CFG const& m_cfg;
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
};
}
diff --git a/libsolidity/analysis/ControlFlowBuilder.h b/libsolidity/analysis/ControlFlowBuilder.h
index e9d96e5f..40605e00 100644
--- a/libsolidity/analysis/ControlFlowBuilder.h
+++ b/libsolidity/analysis/ControlFlowBuilder.h
@@ -46,19 +46,19 @@ public:
private:
explicit ControlFlowBuilder(CFG::NodeContainer& _nodeContainer, FunctionFlow const& _functionFlow);
- virtual bool visit(BinaryOperation const& _operation) override;
- virtual bool visit(Conditional const& _conditional) override;
- virtual bool visit(IfStatement const& _ifStatement) override;
- virtual bool visit(ForStatement const& _forStatement) override;
- virtual bool visit(WhileStatement const& _whileStatement) override;
- virtual bool visit(Break const&) override;
- virtual bool visit(Continue const&) override;
- virtual bool visit(Throw const&) override;
- virtual bool visit(Block const&) override;
- virtual void endVisit(Block const&) override;
- virtual bool visit(Return const& _return) override;
- virtual bool visit(PlaceholderStatement const&) override;
- virtual bool visit(FunctionCall const& _functionCall) override;
+ bool visit(BinaryOperation const& _operation) override;
+ bool visit(Conditional const& _conditional) override;
+ bool visit(IfStatement const& _ifStatement) override;
+ bool visit(ForStatement const& _forStatement) override;
+ bool visit(WhileStatement const& _whileStatement) override;
+ bool visit(Break const&) override;
+ bool visit(Continue const&) override;
+ bool visit(Throw const&) override;
+ bool visit(Block const&) override;
+ void endVisit(Block const&) override;
+ bool visit(Return const& _return) override;
+ bool visit(PlaceholderStatement const&) override;
+ bool visit(FunctionCall const& _functionCall) override;
/// Appends the control flow of @a _node to the current control flow.
@@ -74,7 +74,7 @@ private:
protected:
- virtual bool visitNode(ASTNode const& node) override;
+ bool visitNode(ASTNode const& node) override;
private:
diff --git a/libsolidity/analysis/ControlFlowGraph.cpp b/libsolidity/analysis/ControlFlowGraph.cpp
index 9b3da0eb..b8860158 100644
--- a/libsolidity/analysis/ControlFlowGraph.cpp
+++ b/libsolidity/analysis/ControlFlowGraph.cpp
@@ -23,6 +23,7 @@
#include <algorithm>
using namespace std;
+using namespace langutil;
using namespace dev::solidity;
bool CFG::constructFlow(ASTNode const& _astRoot)
@@ -133,4 +134,4 @@ void CFG::applyModifierFlowToFunctionFlow(
_functionFlow->entry = copySrcToCopyDst[_modifierFlow.entry];
_functionFlow->exit = copySrcToCopyDst[_modifierFlow.exit];
-} \ No newline at end of file
+}
diff --git a/libsolidity/analysis/ControlFlowGraph.h b/libsolidity/analysis/ControlFlowGraph.h
index c646e4f1..8fe9fe8e 100644
--- a/libsolidity/analysis/ControlFlowGraph.h
+++ b/libsolidity/analysis/ControlFlowGraph.h
@@ -19,7 +19,7 @@
#include <libsolidity/ast/AST.h>
#include <libsolidity/ast/ASTVisitor.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
#include <map>
#include <memory>
@@ -101,12 +101,12 @@ struct ModifierFlow: FunctionFlow
class CFG: private ASTConstVisitor
{
public:
- explicit CFG(ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}
+ explicit CFG(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}
bool constructFlow(ASTNode const& _astRoot);
- virtual bool visit(ModifierDefinition const& _modifier) override;
- virtual bool visit(FunctionDefinition const& _function) override;
+ bool visit(ModifierDefinition const& _modifier) override;
+ bool visit(FunctionDefinition const& _function) override;
FunctionFlow const& functionFlow(FunctionDefinition const& _function) const;
@@ -133,7 +133,7 @@ private:
FunctionFlow* _functionFlow
);
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
/// Node container.
/// All nodes allocated during the construction of the control flow graph
diff --git a/libsolidity/analysis/DocStringAnalyser.cpp b/libsolidity/analysis/DocStringAnalyser.cpp
index c1b97def..69a7a43c 100644
--- a/libsolidity/analysis/DocStringAnalyser.cpp
+++ b/libsolidity/analysis/DocStringAnalyser.cpp
@@ -23,11 +23,12 @@
#include <libsolidity/analysis/DocStringAnalyser.h>
#include <libsolidity/ast/AST.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
#include <libsolidity/parsing/DocStringParser.h>
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
bool DocStringAnalyser::analyseDocStrings(SourceUnit const& _sourceUnit)
diff --git a/libsolidity/analysis/DocStringAnalyser.h b/libsolidity/analysis/DocStringAnalyser.h
index 5d339428..f6b236db 100644
--- a/libsolidity/analysis/DocStringAnalyser.h
+++ b/libsolidity/analysis/DocStringAnalyser.h
@@ -25,13 +25,16 @@
#include <libsolidity/ast/ASTVisitor.h>
+namespace langutil
+{
+class ErrorReporter;
+}
+
namespace dev
{
namespace solidity
{
-class ErrorReporter;
-
/**
* Parses and analyses the doc strings.
* Stores the parsing results in the AST annotations and reports errors.
@@ -39,14 +42,14 @@ class ErrorReporter;
class DocStringAnalyser: private ASTConstVisitor
{
public:
- DocStringAnalyser(ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}
+ DocStringAnalyser(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}
bool analyseDocStrings(SourceUnit const& _sourceUnit);
private:
- virtual bool visit(ContractDefinition const& _contract) override;
- virtual bool visit(FunctionDefinition const& _function) override;
- virtual bool visit(ModifierDefinition const& _modifier) override;
- virtual bool visit(EventDefinition const& _event) override;
+ bool visit(ContractDefinition const& _contract) override;
+ bool visit(FunctionDefinition const& _function) override;
+ bool visit(ModifierDefinition const& _modifier) override;
+ bool visit(EventDefinition const& _event) override;
void checkParameters(
CallableDeclaration const& _callable,
@@ -75,7 +78,7 @@ private:
void appendError(std::string const& _description);
bool m_errorOccured = false;
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
};
}
diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp
index b452a49a..e40a2c97 100644
--- a/libsolidity/analysis/NameAndTypeResolver.cpp
+++ b/libsolidity/analysis/NameAndTypeResolver.cpp
@@ -24,12 +24,13 @@
#include <libsolidity/ast/AST.h>
#include <libsolidity/analysis/TypeChecker.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
#include <libdevcore/StringUtils.h>
#include <boost/algorithm/string.hpp>
using namespace std;
+using namespace langutil;
namespace dev
{
@@ -59,7 +60,7 @@ bool NameAndTypeResolver::registerDeclarations(SourceUnit& _sourceUnit, ASTNode
{
DeclarationRegistrationHelper registrar(m_scopes, _sourceUnit, m_errorReporter, _currentScope);
}
- catch (FatalError const&)
+ catch (langutil::FatalError const&)
{
if (m_errorReporter.errors().empty())
throw; // Something is weird here, rather throw again.
@@ -129,7 +130,7 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ASTNode& _node, bool _resolveInsi
{
return resolveNamesAndTypesInternal(_node, _resolveInsideCode);
}
- catch (FatalError const&)
+ catch (langutil::FatalError const&)
{
if (m_errorReporter.errors().empty())
throw; // Something is weird here, rather throw again.
@@ -144,7 +145,7 @@ bool NameAndTypeResolver::updateDeclaration(Declaration const& _declaration)
m_scopes[nullptr]->registerDeclaration(_declaration, nullptr, false, true);
solAssert(_declaration.scope() == nullptr, "Updated declaration outside global scope.");
}
- catch (FatalError const&)
+ catch (langutil::FatalError const&)
{
if (m_errorReporter.errors().empty())
throw; // Something is weird here, rather throw again.
diff --git a/libsolidity/analysis/NameAndTypeResolver.h b/libsolidity/analysis/NameAndTypeResolver.h
index a72c21e3..1b034ef4 100644
--- a/libsolidity/analysis/NameAndTypeResolver.h
+++ b/libsolidity/analysis/NameAndTypeResolver.h
@@ -30,13 +30,16 @@
#include <libsolidity/ast/ASTVisitor.h>
#include <libsolidity/ast/ASTAnnotations.h>
+namespace langutil
+{
+class ErrorReporter;
+}
+
namespace dev
{
namespace solidity
{
-class ErrorReporter;
-
/**
* Resolves name references, typenames and sets the (explicitly given) types for all variable
* declarations.
@@ -50,7 +53,7 @@ public:
NameAndTypeResolver(
std::vector<Declaration const*> const& _globals,
std::map<ASTNode const*, std::shared_ptr<DeclarationContainer>>& _scopes,
- ErrorReporter& _errorReporter
+ langutil::ErrorReporter& _errorReporter
);
/// Registers all declarations found in the AST node, usually a source unit.
/// @returns false in case of error.
@@ -125,7 +128,7 @@ private:
std::map<ASTNode const*, std::shared_ptr<DeclarationContainer>>& m_scopes;
DeclarationContainer* m_currentScope = nullptr;
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
};
/**
@@ -142,7 +145,7 @@ public:
DeclarationRegistrationHelper(
std::map<ASTNode const*, std::shared_ptr<DeclarationContainer>>& _scopes,
ASTNode& _astRoot,
- ErrorReporter& _errorReporter,
+ langutil::ErrorReporter& _errorReporter,
ASTNode const* _currentScope = nullptr
);
@@ -150,10 +153,10 @@ public:
DeclarationContainer& _container,
Declaration const& _declaration,
std::string const* _name,
- SourceLocation const* _errorLocation,
+ langutil::SourceLocation const* _errorLocation,
bool _warnOnShadow,
bool _inactive,
- ErrorReporter& _errorReporter
+ langutil::ErrorReporter& _errorReporter
);
private:
@@ -194,7 +197,7 @@ private:
std::map<ASTNode const*, std::shared_ptr<DeclarationContainer>>& m_scopes;
ASTNode const* m_currentScope = nullptr;
VariableScope* m_currentFunction = nullptr;
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
};
}
diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp
index 240d7973..27cbcd45 100644
--- a/libsolidity/analysis/PostTypeChecker.cpp
+++ b/libsolidity/analysis/PostTypeChecker.cpp
@@ -18,7 +18,7 @@
#include <libsolidity/analysis/PostTypeChecker.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/analysis/SemVerHandler.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
#include <libsolidity/interface/Version.h>
#include <libdevcore/Algorithms.h>
@@ -29,6 +29,7 @@
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
diff --git a/libsolidity/analysis/PostTypeChecker.h b/libsolidity/analysis/PostTypeChecker.h
index 4f9dac6e..e428b81a 100644
--- a/libsolidity/analysis/PostTypeChecker.h
+++ b/libsolidity/analysis/PostTypeChecker.h
@@ -23,13 +23,17 @@
#include <libsolidity/ast/ASTForward.h>
#include <libsolidity/ast/ASTVisitor.h>
+namespace langutil
+{
+class ErrorReporter;
+struct SourceLocation;
+}
+
namespace dev
{
namespace solidity
{
-class ErrorReporter;
-
/**
* This module performs analyses on the AST that are done after type checking and assignments of types:
* - whether there are circular references in constant state variables
@@ -39,25 +43,25 @@ class PostTypeChecker: private ASTConstVisitor
{
public:
/// @param _errorReporter provides the error logging functionality.
- PostTypeChecker(ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}
+ PostTypeChecker(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}
bool check(ASTNode const& _astRoot);
private:
/// Adds a new error to the list of errors.
- void typeError(SourceLocation const& _location, std::string const& _description);
+ void typeError(langutil::SourceLocation const& _location, std::string const& _description);
- virtual bool visit(ContractDefinition const& _contract) override;
- virtual void endVisit(ContractDefinition const& _contract) override;
+ bool visit(ContractDefinition const& _contract) override;
+ void endVisit(ContractDefinition const& _contract) override;
- virtual bool visit(VariableDeclaration const& _variable) override;
- virtual void endVisit(VariableDeclaration const& _variable) override;
+ bool visit(VariableDeclaration const& _variable) override;
+ void endVisit(VariableDeclaration const& _variable) override;
- virtual bool visit(Identifier const& _identifier) override;
+ bool visit(Identifier const& _identifier) override;
VariableDeclaration const* findCycle(VariableDeclaration const& _startingFrom);
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
VariableDeclaration const* m_currentConstVariable = nullptr;
std::vector<VariableDeclaration const*> m_constVariables; ///< Required for determinism.
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp
index 2adc8e77..c4931d98 100644
--- a/libsolidity/analysis/ReferencesResolver.cpp
+++ b/libsolidity/analysis/ReferencesResolver.cpp
@@ -23,12 +23,12 @@
#include <libsolidity/analysis/ReferencesResolver.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/analysis/NameAndTypeResolver.h>
-#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/analysis/ConstantEvaluator.h>
-#include <libsolidity/inlineasm/AsmAnalysis.h>
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
-#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <libyul/AsmAnalysis.h>
+#include <libyul/AsmAnalysisInfo.h>
+#include <libyul/AsmData.h>
+#include <liblangutil/ErrorReporter.h>
+#include <liblangutil/Exceptions.h>
#include <libdevcore/StringUtils.h>
@@ -36,9 +36,12 @@
#include <boost/range/adaptor/transformed.hpp>
using namespace std;
-using namespace dev;
-using namespace dev::solidity;
+using namespace langutil;
+namespace dev
+{
+namespace solidity
+{
bool ReferencesResolver::resolve(ASTNode const& _root)
{
@@ -270,7 +273,7 @@ bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly)
ErrorList errors;
ErrorReporter errorsIgnored(errors);
yul::ExternalIdentifierAccess::Resolver resolver =
- [&](assembly::Identifier const& _identifier, yul::IdentifierContext, bool _crossesFunctionBoundary) {
+ [&](yul::Identifier const& _identifier, yul::IdentifierContext, bool _crossesFunctionBoundary) {
auto declarations = m_resolver.nameFromCurrentScope(_identifier.name.str());
bool isSlot = boost::algorithm::ends_with(_identifier.name.str(), "_slot");
bool isOffset = boost::algorithm::ends_with(_identifier.name.str(), "_offset");
@@ -311,9 +314,9 @@ bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly)
// Will be re-generated later with correct information
// We use the latest EVM version because we will re-run it anyway.
- assembly::AsmAnalysisInfo analysisInfo;
+ yul::AsmAnalysisInfo analysisInfo;
boost::optional<Error::Type> errorTypeForLoose = Error::Type::SyntaxError;
- assembly::AsmAnalyzer(analysisInfo, errorsIgnored, EVMVersion(), errorTypeForLoose, assembly::AsmFlavour::Loose, resolver).analyze(_inlineAssembly.operations());
+ yul::AsmAnalyzer(analysisInfo, errorsIgnored, EVMVersion(), errorTypeForLoose, yul::AsmFlavour::Loose, resolver).analyze(_inlineAssembly.operations());
return false;
}
@@ -454,3 +457,6 @@ void ReferencesResolver::fatalDeclarationError(SourceLocation const& _location,
m_errorOccurred = true;
m_errorReporter.fatalDeclarationError(_location, _description);
}
+
+}
+}
diff --git a/libsolidity/analysis/ReferencesResolver.h b/libsolidity/analysis/ReferencesResolver.h
index 24ec4643..32c0553f 100644
--- a/libsolidity/analysis/ReferencesResolver.h
+++ b/libsolidity/analysis/ReferencesResolver.h
@@ -28,12 +28,17 @@
#include <libsolidity/ast/ASTVisitor.h>
#include <libsolidity/ast/ASTAnnotations.h>
+namespace langutil
+{
+class ErrorReporter;
+struct SourceLocation;
+}
+
namespace dev
{
namespace solidity
{
-class ErrorReporter;
class NameAndTypeResolver;
/**
@@ -44,7 +49,7 @@ class ReferencesResolver: private ASTConstVisitor
{
public:
ReferencesResolver(
- ErrorReporter& _errorReporter,
+ langutil::ErrorReporter& _errorReporter,
NameAndTypeResolver& _resolver,
bool _resolveInsideCode = false
):
@@ -57,38 +62,38 @@ public:
bool resolve(ASTNode const& _root);
private:
- virtual bool visit(Block const& _block) override;
- virtual void endVisit(Block const& _block) override;
- virtual bool visit(ForStatement const& _for) override;
- virtual void endVisit(ForStatement const& _for) override;
- virtual void endVisit(VariableDeclarationStatement const& _varDeclStatement) override;
- virtual bool visit(Identifier const& _identifier) override;
- virtual bool visit(ElementaryTypeName const& _typeName) override;
- virtual bool visit(FunctionDefinition const& _functionDefinition) override;
- virtual void endVisit(FunctionDefinition const& _functionDefinition) override;
- virtual bool visit(ModifierDefinition const& _modifierDefinition) override;
- virtual void endVisit(ModifierDefinition const& _modifierDefinition) override;
- virtual void endVisit(UserDefinedTypeName const& _typeName) override;
- virtual void endVisit(FunctionTypeName const& _typeName) override;
- virtual void endVisit(Mapping const& _typeName) override;
- virtual void endVisit(ArrayTypeName const& _typeName) override;
- virtual bool visit(InlineAssembly const& _inlineAssembly) override;
- virtual bool visit(Return const& _return) override;
- virtual void endVisit(VariableDeclaration const& _variable) override;
+ bool visit(Block const& _block) override;
+ void endVisit(Block const& _block) override;
+ bool visit(ForStatement const& _for) override;
+ void endVisit(ForStatement const& _for) override;
+ void endVisit(VariableDeclarationStatement const& _varDeclStatement) override;
+ bool visit(Identifier const& _identifier) override;
+ bool visit(ElementaryTypeName const& _typeName) override;
+ bool visit(FunctionDefinition const& _functionDefinition) override;
+ void endVisit(FunctionDefinition const& _functionDefinition) override;
+ bool visit(ModifierDefinition const& _modifierDefinition) override;
+ void endVisit(ModifierDefinition const& _modifierDefinition) override;
+ void endVisit(UserDefinedTypeName const& _typeName) override;
+ void endVisit(FunctionTypeName const& _typeName) override;
+ void endVisit(Mapping const& _typeName) override;
+ void endVisit(ArrayTypeName const& _typeName) override;
+ bool visit(InlineAssembly const& _inlineAssembly) override;
+ bool visit(Return const& _return) override;
+ void endVisit(VariableDeclaration const& _variable) override;
/// Adds a new error to the list of errors.
- void typeError(SourceLocation const& _location, std::string const& _description);
+ void typeError(langutil::SourceLocation const& _location, std::string const& _description);
/// Adds a new error to the list of errors and throws to abort reference resolving.
- void fatalTypeError(SourceLocation const& _location, std::string const& _description);
+ void fatalTypeError(langutil::SourceLocation const& _location, std::string const& _description);
/// Adds a new error to the list of errors.
- void declarationError(SourceLocation const& _location, std::string const& _description);
+ void declarationError(langutil::SourceLocation const& _location, std::string const& _description);
/// Adds a new error to the list of errors and throws to abort reference resolving.
- void fatalDeclarationError(SourceLocation const& _location, std::string const& _description);
+ void fatalDeclarationError(langutil::SourceLocation const& _location, std::string const& _description);
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
NameAndTypeResolver& m_resolver;
/// Stack of return parameters.
std::vector<ParameterList const*> m_returnParameters;
diff --git a/libsolidity/analysis/SemVerHandler.h b/libsolidity/analysis/SemVerHandler.h
index 03a557c5..80185612 100644
--- a/libsolidity/analysis/SemVerHandler.h
+++ b/libsolidity/analysis/SemVerHandler.h
@@ -22,8 +22,9 @@
#pragma once
-#include <vector>
#include <libsolidity/parsing/Token.h>
+#include <string>
+#include <vector>
namespace dev
{
diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp
index 487a5cca..38391841 100644
--- a/libsolidity/analysis/StaticAnalyzer.cpp
+++ b/libsolidity/analysis/StaticAnalyzer.cpp
@@ -23,11 +23,12 @@
#include <libsolidity/analysis/StaticAnalyzer.h>
#include <libsolidity/analysis/ConstantEvaluator.h>
#include <libsolidity/ast/AST.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
#include <memory>
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
bool StaticAnalyzer::analyze(SourceUnit const& _sourceUnit)
diff --git a/libsolidity/analysis/StaticAnalyzer.h b/libsolidity/analysis/StaticAnalyzer.h
index 7f5c743a..ff33fa3a 100644
--- a/libsolidity/analysis/StaticAnalyzer.h
+++ b/libsolidity/analysis/StaticAnalyzer.h
@@ -28,6 +28,11 @@
#include <libsolidity/ast/ASTForward.h>
#include <libsolidity/ast/ASTVisitor.h>
+namespace langutil
+{
+class ErrorReporter;
+}
+
namespace dev
{
namespace solidity
@@ -44,7 +49,7 @@ class StaticAnalyzer: private ASTConstVisitor
{
public:
/// @param _errorReporter provides the error logging functionality.
- explicit StaticAnalyzer(ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}
+ explicit StaticAnalyzer(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}
/// Performs static analysis on the given source unit and all of its sub-nodes.
/// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings
@@ -52,25 +57,25 @@ public:
private:
- virtual bool visit(ContractDefinition const& _contract) override;
- virtual void endVisit(ContractDefinition const& _contract) override;
+ bool visit(ContractDefinition const& _contract) override;
+ void endVisit(ContractDefinition const& _contract) override;
- virtual bool visit(FunctionDefinition const& _function) override;
- virtual void endVisit(FunctionDefinition const& _function) override;
+ bool visit(FunctionDefinition const& _function) override;
+ void endVisit(FunctionDefinition const& _function) override;
- virtual bool visit(ExpressionStatement const& _statement) override;
- virtual bool visit(VariableDeclaration const& _variable) override;
- virtual bool visit(Identifier const& _identifier) override;
- virtual bool visit(Return const& _return) override;
- virtual bool visit(MemberAccess const& _memberAccess) override;
- virtual bool visit(InlineAssembly const& _inlineAssembly) override;
- virtual bool visit(BinaryOperation const& _operation) override;
- virtual bool visit(FunctionCall const& _functionCall) override;
+ bool visit(ExpressionStatement const& _statement) override;
+ bool visit(VariableDeclaration const& _variable) override;
+ bool visit(Identifier const& _identifier) override;
+ bool visit(Return const& _return) override;
+ bool visit(MemberAccess const& _memberAccess) override;
+ bool visit(InlineAssembly const& _inlineAssembly) override;
+ bool visit(BinaryOperation const& _operation) override;
+ bool visit(FunctionCall const& _functionCall) override;
/// @returns the size of this type in storage, including all sub-types.
static bigint structureSizeEstimate(Type const& _type, std::set<StructDefinition const*>& _structsSeen);
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
/// Flag that indicates whether the current contract definition is a library.
bool m_library = false;
diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp
index 3f9f8373..a73d7e5c 100644
--- a/libsolidity/analysis/SyntaxChecker.cpp
+++ b/libsolidity/analysis/SyntaxChecker.cpp
@@ -20,7 +20,7 @@
#include <libsolidity/ast/AST.h>
#include <libsolidity/ast/ExperimentalFeatures.h>
#include <libsolidity/analysis/SemVerHandler.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
#include <libsolidity/interface/Version.h>
#include <boost/algorithm/cxx11/all_of.hpp>
@@ -29,6 +29,7 @@
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
diff --git a/libsolidity/analysis/SyntaxChecker.h b/libsolidity/analysis/SyntaxChecker.h
index f5716bf9..c2463955 100644
--- a/libsolidity/analysis/SyntaxChecker.h
+++ b/libsolidity/analysis/SyntaxChecker.h
@@ -23,6 +23,11 @@
#include <libsolidity/ast/ASTForward.h>
#include <libsolidity/ast/ASTVisitor.h>
+namespace langutil
+{
+class ErrorReporter;
+}
+
namespace dev
{
namespace solidity
@@ -39,49 +44,49 @@ class SyntaxChecker: private ASTConstVisitor
{
public:
/// @param _errorReporter provides the error logging functionality.
- SyntaxChecker(ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}
+ SyntaxChecker(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}
bool checkSyntax(ASTNode const& _astRoot);
private:
- virtual bool visit(SourceUnit const& _sourceUnit) override;
- virtual void endVisit(SourceUnit const& _sourceUnit) override;
- virtual bool visit(PragmaDirective const& _pragma) override;
+ bool visit(SourceUnit const& _sourceUnit) override;
+ void endVisit(SourceUnit const& _sourceUnit) override;
+ bool visit(PragmaDirective const& _pragma) override;
- virtual bool visit(ModifierDefinition const& _modifier) override;
- virtual void endVisit(ModifierDefinition const& _modifier) override;
+ bool visit(ModifierDefinition const& _modifier) override;
+ void endVisit(ModifierDefinition const& _modifier) override;
/// Reports an error if _statement is a VariableDeclarationStatement.
/// Used by if/while/for to check for single statement variable declarations
/// without a block.
void checkSingleStatementVariableDeclaration(ASTNode const& _statement);
- virtual bool visit(IfStatement const& _ifStatement) override;
- virtual bool visit(WhileStatement const& _whileStatement) override;
- virtual void endVisit(WhileStatement const& _whileStatement) override;
- virtual bool visit(ForStatement const& _forStatement) override;
- virtual void endVisit(ForStatement const& _forStatement) override;
+ bool visit(IfStatement const& _ifStatement) override;
+ bool visit(WhileStatement const& _whileStatement) override;
+ void endVisit(WhileStatement const& _whileStatement) override;
+ bool visit(ForStatement const& _forStatement) override;
+ void endVisit(ForStatement const& _forStatement) override;
- virtual bool visit(Continue const& _continueStatement) override;
- virtual bool visit(Break const& _breakStatement) override;
+ bool visit(Continue const& _continueStatement) override;
+ bool visit(Break const& _breakStatement) override;
- virtual bool visit(Throw const& _throwStatement) override;
+ bool visit(Throw const& _throwStatement) override;
- virtual bool visit(UnaryOperation const& _operation) override;
+ bool visit(UnaryOperation const& _operation) override;
- virtual bool visit(PlaceholderStatement const& _placeholderStatement) override;
+ bool visit(PlaceholderStatement const& _placeholderStatement) override;
- virtual bool visit(ContractDefinition const& _contract) override;
- virtual bool visit(FunctionDefinition const& _function) override;
- virtual bool visit(FunctionTypeName const& _node) override;
+ bool visit(ContractDefinition const& _contract) override;
+ bool visit(FunctionDefinition const& _function) override;
+ bool visit(FunctionTypeName const& _node) override;
- virtual bool visit(VariableDeclarationStatement const& _statement) override;
+ bool visit(VariableDeclarationStatement const& _statement) override;
- virtual bool visit(StructDefinition const& _struct) override;
- virtual bool visit(Literal const& _literal) override;
+ bool visit(StructDefinition const& _struct) override;
+ bool visit(Literal const& _literal) override;
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
/// Flag that indicates whether a function modifier actually contains '_'.
bool m_placeholderFound = false;
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index c5e6488b..d503b9ec 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -27,14 +27,15 @@
#include <boost/algorithm/string/join.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <libsolidity/ast/AST.h>
-#include <libsolidity/inlineasm/AsmAnalysis.h>
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
-#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <libyul/AsmAnalysis.h>
+#include <libyul/AsmAnalysisInfo.h>
+#include <libyul/AsmData.h>
+#include <liblangutil/ErrorReporter.h>
#include <libdevcore/Algorithms.h>
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
namespace
@@ -399,42 +400,39 @@ void TypeChecker::checkContractIllegalOverrides(ContractDefinition const& _contr
}
}
-void TypeChecker::checkFunctionOverride(FunctionDefinition const& function, FunctionDefinition const& super)
+void TypeChecker::checkFunctionOverride(FunctionDefinition const& _function, FunctionDefinition const& _super)
{
- FunctionType functionType(function);
- FunctionType superType(super);
+ FunctionType functionType(_function);
+ FunctionType superType(_super);
if (!functionType.hasEqualParameterTypes(superType))
return;
- if (!function.annotation().superFunction)
- function.annotation().superFunction = &super;
+ if (!_function.annotation().superFunction)
+ _function.annotation().superFunction = &_super;
- if (function.visibility() != super.visibility())
+ if (_function.visibility() != _super.visibility())
{
- // visibility is enforced to be external in interfaces, but a contract can override that with public
- if (
- super.inContractKind() == ContractDefinition::ContractKind::Interface &&
- function.inContractKind() != ContractDefinition::ContractKind::Interface &&
- function.visibility() == FunctionDefinition::Visibility::Public
- )
- return;
- overrideError(function, super, "Overriding function visibility differs.");
+ // Visibility change from external to public is fine.
+ // Any other change is disallowed.
+ if (!(
+ _super.visibility() == FunctionDefinition::Visibility::External &&
+ _function.visibility() == FunctionDefinition::Visibility::Public
+ ))
+ overrideError(_function, _super, "Overriding function visibility differs.");
}
-
- else if (function.stateMutability() != super.stateMutability())
+ else if (_function.stateMutability() != _super.stateMutability())
overrideError(
- function,
- super,
+ _function,
+ _super,
"Overriding function changes state mutability from \"" +
- stateMutabilityToString(super.stateMutability()) +
+ stateMutabilityToString(_super.stateMutability()) +
"\" to \"" +
- stateMutabilityToString(function.stateMutability()) +
+ stateMutabilityToString(_function.stateMutability()) +
"\"."
);
-
else if (functionType != superType)
- overrideError(function, super, "Overriding function return types differ.");
+ overrideError(_function, _super, "Overriding function return types differ.");
}
void TypeChecker::overrideError(FunctionDefinition const& function, FunctionDefinition const& super, string message)
@@ -953,7 +951,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
// External references have already been resolved in a prior stage and stored in the annotation.
// We run the resolve step again regardless.
yul::ExternalIdentifierAccess::Resolver identifierAccess = [&](
- assembly::Identifier const& _identifier,
+ yul::Identifier const& _identifier,
yul::IdentifierContext _context,
bool
)
@@ -1038,13 +1036,13 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
return size_t(1);
};
solAssert(!_inlineAssembly.annotation().analysisInfo, "");
- _inlineAssembly.annotation().analysisInfo = make_shared<assembly::AsmAnalysisInfo>();
- assembly::AsmAnalyzer analyzer(
+ _inlineAssembly.annotation().analysisInfo = make_shared<yul::AsmAnalysisInfo>();
+ yul::AsmAnalyzer analyzer(
*_inlineAssembly.annotation().analysisInfo,
m_errorReporter,
m_evmVersion,
Error::Type::SyntaxError,
- assembly::AsmFlavour::Loose,
+ yul::AsmFlavour::Loose,
identifierAccess
);
if (!analyzer.analyze(_inlineAssembly.operations()))
diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h
index c76fa466..c98a4c7f 100644
--- a/libsolidity/analysis/TypeChecker.h
+++ b/libsolidity/analysis/TypeChecker.h
@@ -22,20 +22,23 @@
#pragma once
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <libsolidity/ast/Types.h>
#include <libsolidity/ast/ASTAnnotations.h>
#include <libsolidity/ast/ASTForward.h>
#include <libsolidity/ast/ASTVisitor.h>
+namespace langutil
+{
+class ErrorReporter;
+}
+
namespace dev
{
namespace solidity
{
-class ErrorReporter;
-
/**
* The module that performs type analysis on the AST, checks the applicability of operations on
* those types and stores errors for invalid operations.
@@ -45,7 +48,7 @@ class TypeChecker: private ASTConstVisitor
{
public:
/// @param _errorReporter provides the error logging functionality.
- TypeChecker(EVMVersion _evmVersion, ErrorReporter& _errorReporter):
+ TypeChecker(EVMVersion _evmVersion, langutil::ErrorReporter& _errorReporter):
m_evmVersion(_evmVersion),
m_errorReporter(_errorReporter)
{}
@@ -62,7 +65,7 @@ public:
private:
- virtual bool visit(ContractDefinition const& _contract) override;
+ bool visit(ContractDefinition const& _contract) override;
/// Checks that two functions defined in this contract with the same name have different
/// arguments and that there is at most one constructor.
void checkContractDuplicateFunctions(ContractDefinition const& _contract);
@@ -122,37 +125,37 @@ private:
FunctionTypePointer _functionType
);
- virtual void endVisit(InheritanceSpecifier const& _inheritance) override;
- virtual void endVisit(UsingForDirective const& _usingFor) override;
- virtual bool visit(StructDefinition const& _struct) override;
- virtual bool visit(FunctionDefinition const& _function) override;
- virtual bool visit(VariableDeclaration const& _variable) override;
+ void endVisit(InheritanceSpecifier const& _inheritance) override;
+ void endVisit(UsingForDirective const& _usingFor) override;
+ bool visit(StructDefinition const& _struct) override;
+ bool visit(FunctionDefinition const& _function) override;
+ bool visit(VariableDeclaration const& _variable) override;
/// We need to do this manually because we want to pass the bases of the current contract in
/// case this is a base constructor call.
void visitManually(ModifierInvocation const& _modifier, std::vector<ContractDefinition const*> const& _bases);
- virtual bool visit(EventDefinition const& _eventDef) override;
- virtual void endVisit(FunctionTypeName const& _funType) override;
- virtual bool visit(InlineAssembly const& _inlineAssembly) override;
- virtual bool visit(IfStatement const& _ifStatement) override;
- virtual bool visit(WhileStatement const& _whileStatement) override;
- virtual bool visit(ForStatement const& _forStatement) override;
- virtual void endVisit(Return const& _return) override;
- virtual bool visit(EmitStatement const&) override { m_insideEmitStatement = true; return true; }
- virtual void endVisit(EmitStatement const& _emit) override;
- virtual bool visit(VariableDeclarationStatement const& _variable) override;
- virtual void endVisit(ExpressionStatement const& _statement) override;
- virtual bool visit(Conditional const& _conditional) override;
- virtual bool visit(Assignment const& _assignment) override;
- virtual bool visit(TupleExpression const& _tuple) override;
- virtual void endVisit(BinaryOperation const& _operation) override;
- virtual bool visit(UnaryOperation const& _operation) override;
- virtual bool visit(FunctionCall const& _functionCall) override;
- virtual void endVisit(NewExpression const& _newExpression) override;
- virtual bool visit(MemberAccess const& _memberAccess) override;
- virtual bool visit(IndexAccess const& _indexAccess) override;
- virtual bool visit(Identifier const& _identifier) override;
- virtual void endVisit(ElementaryTypeNameExpression const& _expr) override;
- virtual void endVisit(Literal const& _literal) override;
+ bool visit(EventDefinition const& _eventDef) override;
+ void endVisit(FunctionTypeName const& _funType) override;
+ bool visit(InlineAssembly const& _inlineAssembly) override;
+ bool visit(IfStatement const& _ifStatement) override;
+ bool visit(WhileStatement const& _whileStatement) override;
+ bool visit(ForStatement const& _forStatement) override;
+ void endVisit(Return const& _return) override;
+ bool visit(EmitStatement const&) override { m_insideEmitStatement = true; return true; }
+ void endVisit(EmitStatement const& _emit) override;
+ bool visit(VariableDeclarationStatement const& _variable) override;
+ void endVisit(ExpressionStatement const& _statement) override;
+ bool visit(Conditional const& _conditional) override;
+ bool visit(Assignment const& _assignment) override;
+ bool visit(TupleExpression const& _tuple) override;
+ void endVisit(BinaryOperation const& _operation) override;
+ bool visit(UnaryOperation const& _operation) override;
+ bool visit(FunctionCall const& _functionCall) override;
+ void endVisit(NewExpression const& _newExpression) override;
+ bool visit(MemberAccess const& _memberAccess) override;
+ bool visit(IndexAccess const& _indexAccess) override;
+ bool visit(Identifier const& _identifier) override;
+ void endVisit(ElementaryTypeNameExpression const& _expr) override;
+ void endVisit(Literal const& _literal) override;
template <class T>
void findDuplicateDefinitions(std::map<std::string, std::vector<T>> const& _definitions, std::string _message);
@@ -183,7 +186,7 @@ private:
/// Flag indicating whether we are currently inside a StructDefinition.
bool m_insideStruct = false;
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
};
}
diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp
index b0cacc43..1112d682 100644
--- a/libsolidity/analysis/ViewPureChecker.cpp
+++ b/libsolidity/analysis/ViewPureChecker.cpp
@@ -19,13 +19,16 @@
#include <libevmasm/SemanticInformation.h>
-#include <libsolidity/inlineasm/AsmData.h>
#include <libsolidity/ast/ExperimentalFeatures.h>
+#include <libyul/AsmData.h>
+
+#include <liblangutil/ErrorReporter.h>
#include <functional>
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
namespace
@@ -37,48 +40,48 @@ public:
explicit AssemblyViewPureChecker(std::function<void(StateMutability, SourceLocation const&)> _reportMutability):
m_reportMutability(_reportMutability) {}
- void operator()(assembly::Label const&) { }
- void operator()(assembly::Instruction const& _instruction)
+ void operator()(yul::Label const&) { }
+ void operator()(yul::Instruction const& _instruction)
{
checkInstruction(_instruction.location, _instruction.instruction);
}
- void operator()(assembly::Literal const&) {}
- void operator()(assembly::Identifier const&) {}
- void operator()(assembly::FunctionalInstruction const& _instr)
+ void operator()(yul::Literal const&) {}
+ void operator()(yul::Identifier const&) {}
+ void operator()(yul::FunctionalInstruction const& _instr)
{
checkInstruction(_instr.location, _instr.instruction);
for (auto const& arg: _instr.arguments)
boost::apply_visitor(*this, arg);
}
- void operator()(assembly::ExpressionStatement const& _expr)
+ void operator()(yul::ExpressionStatement const& _expr)
{
boost::apply_visitor(*this, _expr.expression);
}
- void operator()(assembly::StackAssignment const&) {}
- void operator()(assembly::Assignment const& _assignment)
+ void operator()(yul::StackAssignment const&) {}
+ void operator()(yul::Assignment const& _assignment)
{
boost::apply_visitor(*this, *_assignment.value);
}
- void operator()(assembly::VariableDeclaration const& _varDecl)
+ void operator()(yul::VariableDeclaration const& _varDecl)
{
if (_varDecl.value)
boost::apply_visitor(*this, *_varDecl.value);
}
- void operator()(assembly::FunctionDefinition const& _funDef)
+ void operator()(yul::FunctionDefinition const& _funDef)
{
(*this)(_funDef.body);
}
- void operator()(assembly::FunctionCall const& _funCall)
+ void operator()(yul::FunctionCall const& _funCall)
{
for (auto const& arg: _funCall.arguments)
boost::apply_visitor(*this, arg);
}
- void operator()(assembly::If const& _if)
+ void operator()(yul::If const& _if)
{
boost::apply_visitor(*this, *_if.condition);
(*this)(_if.body);
}
- void operator()(assembly::Switch const& _switch)
+ void operator()(yul::Switch const& _switch)
{
boost::apply_visitor(*this, *_switch.expression);
for (auto const& _case: _switch.cases)
@@ -88,14 +91,14 @@ public:
(*this)(_case.body);
}
}
- void operator()(assembly::ForLoop const& _for)
+ void operator()(yul::ForLoop const& _for)
{
(*this)(_for.pre);
boost::apply_visitor(*this, *_for.condition);
(*this)(_for.body);
(*this)(_for.post);
}
- void operator()(assembly::Block const& _block)
+ void operator()(yul::Block const& _block)
{
for (auto const& s: _block.statements)
boost::apply_visitor(*this, s);
diff --git a/libsolidity/analysis/ViewPureChecker.h b/libsolidity/analysis/ViewPureChecker.h
index faa5b698..fd2432a7 100644
--- a/libsolidity/analysis/ViewPureChecker.h
+++ b/libsolidity/analysis/ViewPureChecker.h
@@ -21,11 +21,15 @@
#include <libsolidity/ast/ASTForward.h>
#include <libsolidity/ast/ASTVisitor.h>
-#include <libsolidity/interface/ErrorReporter.h>
-
#include <map>
#include <memory>
+namespace langutil
+{
+class ErrorReporter;
+struct SourceLocation;
+}
+
namespace dev
{
namespace solidity
@@ -34,7 +38,7 @@ namespace solidity
class ViewPureChecker: private ASTConstVisitor
{
public:
- ViewPureChecker(std::vector<std::shared_ptr<ASTNode>> const& _ast, ErrorReporter& _errorReporter):
+ ViewPureChecker(std::vector<std::shared_ptr<ASTNode>> const& _ast, langutil::ErrorReporter& _errorReporter):
m_ast(_ast), m_errorReporter(_errorReporter) {}
bool check();
@@ -43,34 +47,34 @@ private:
struct MutabilityAndLocation
{
StateMutability mutability;
- SourceLocation location;
+ langutil::SourceLocation location;
};
- virtual bool visit(FunctionDefinition const& _funDef) override;
- virtual void endVisit(FunctionDefinition const& _funDef) override;
- virtual bool visit(ModifierDefinition const& _modifierDef) override;
- virtual void endVisit(ModifierDefinition const& _modifierDef) override;
- virtual void endVisit(Identifier const& _identifier) override;
- virtual bool visit(MemberAccess const& _memberAccess) override;
- virtual void endVisit(MemberAccess const& _memberAccess) override;
- virtual void endVisit(IndexAccess const& _indexAccess) override;
- virtual void endVisit(ModifierInvocation const& _modifier) override;
- virtual void endVisit(FunctionCall const& _functionCall) override;
- virtual void endVisit(InlineAssembly const& _inlineAssembly) override;
+ bool visit(FunctionDefinition const& _funDef) override;
+ void endVisit(FunctionDefinition const& _funDef) override;
+ bool visit(ModifierDefinition const& _modifierDef) override;
+ void endVisit(ModifierDefinition const& _modifierDef) override;
+ void endVisit(Identifier const& _identifier) override;
+ bool visit(MemberAccess const& _memberAccess) override;
+ void endVisit(MemberAccess const& _memberAccess) override;
+ void endVisit(IndexAccess const& _indexAccess) override;
+ void endVisit(ModifierInvocation const& _modifier) override;
+ void endVisit(FunctionCall const& _functionCall) override;
+ void endVisit(InlineAssembly const& _inlineAssembly) override;
/// Called when an element of mutability @a _mutability is encountered.
/// Creates appropriate warnings and errors and sets @a m_currentBestMutability.
void reportMutability(
StateMutability _mutability,
- SourceLocation const& _location,
- boost::optional<SourceLocation> const& _nestedLocation = {}
+ langutil::SourceLocation const& _location,
+ boost::optional<langutil::SourceLocation> const& _nestedLocation = {}
);
std::vector<std::shared_ptr<ASTNode>> const& m_ast;
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
bool m_errors = false;
- MutabilityAndLocation m_bestMutabilityAndLocation = MutabilityAndLocation{StateMutability::Payable, SourceLocation()};
+ MutabilityAndLocation m_bestMutabilityAndLocation = MutabilityAndLocation{StateMutability::Payable, langutil::SourceLocation()};
FunctionDefinition const* m_currentFunction = nullptr;
std::map<ModifierDefinition const*, MutabilityAndLocation> m_inferredMutability;
};
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index 4fd2bcb8..2f418b09 100644
--- a/libsolidity/ast/AST.h
+++ b/libsolidity/ast/AST.h
@@ -23,13 +23,13 @@
#pragma once
-#include <libsolidity/ast/ASTForward.h>
#include <libsolidity/parsing/Token.h>
+#include <libsolidity/ast/ASTForward.h>
#include <libsolidity/ast/Types.h>
#include <libsolidity/ast/ASTAnnotations.h>
#include <libsolidity/ast/ASTEnums.h>
-#include <libevmasm/SourceLocation.h>
+#include <liblangutil/SourceLocation.h>
#include <libevmasm/Instruction.h>
#include <libdevcore/FixedHash.h>
@@ -41,6 +41,12 @@
#include <vector>
#include <memory>
+namespace yul
+{
+// Forward-declaration to <yul/AsmData.h>
+struct Block;
+}
+
namespace dev
{
namespace solidity
@@ -58,6 +64,8 @@ class ASTConstVisitor;
class ASTNode: private boost::noncopyable
{
public:
+ using SourceLocation = langutil::SourceLocation;
+
explicit ASTNode(SourceLocation const& _location);
virtual ~ASTNode();
@@ -126,9 +134,9 @@ public:
SourceUnit(SourceLocation const& _location, std::vector<ASTPointer<ASTNode>> const& _nodes):
ASTNode(_location), m_nodes(_nodes) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
- virtual SourceUnitAnnotation& annotation() const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
+ SourceUnitAnnotation& annotation() const override;
std::vector<ASTPointer<ASTNode>> nodes() const { return m_nodes; }
@@ -242,8 +250,8 @@ public:
): ASTNode(_location), m_tokens(_tokens), m_literals(_literals)
{}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
std::vector<Token> const& tokens() const { return m_tokens; }
std::vector<ASTString> const& literals() const { return m_literals; }
@@ -279,17 +287,17 @@ public:
m_symbolAliases(_symbolAliases)
{ }
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
ASTString const& path() const { return *m_path; }
std::vector<std::pair<ASTPointer<Identifier>, ASTPointer<ASTString>>> const& symbolAliases() const
{
return m_symbolAliases;
}
- virtual ImportAnnotation& annotation() const override;
+ ImportAnnotation& annotation() const override;
- virtual TypePointer type() const override;
+ TypePointer type() const override;
private:
ASTPointer<ASTString> m_path;
@@ -375,8 +383,8 @@ public:
m_contractKind(_contractKind)
{}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
std::vector<ASTPointer<InheritanceSpecifier>> const& baseContracts() const { return m_baseContracts; }
std::vector<ASTPointer<ASTNode>> const& subNodes() const { return m_subNodes; }
@@ -407,9 +415,9 @@ public:
std::string fullyQualifiedName() const { return sourceUnitName() + ":" + name(); }
- virtual TypePointer type() const override;
+ TypePointer type() const override;
- virtual ContractDefinitionAnnotation& annotation() const override;
+ ContractDefinitionAnnotation& annotation() const override;
ContractKind contractKind() const { return m_contractKind; }
@@ -434,8 +442,8 @@ public:
):
ASTNode(_location), m_baseName(_baseName), m_arguments(std::move(_arguments)) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
UserDefinedTypeName const& name() const { return *m_baseName; }
// Returns nullptr if no argument list was given (``C``).
@@ -463,8 +471,8 @@ public:
):
ASTNode(_location), m_libraryName(_libraryName), m_typeName(_typeName) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
UserDefinedTypeName const& libraryName() const { return *m_libraryName; }
/// @returns the type name the library is attached to, null for `*`.
@@ -485,14 +493,14 @@ public:
):
Declaration(_location, _name), m_members(_members) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
std::vector<ASTPointer<VariableDeclaration>> const& members() const { return m_members; }
- virtual TypePointer type() const override;
+ TypePointer type() const override;
- virtual TypeDeclarationAnnotation& annotation() const override;
+ TypeDeclarationAnnotation& annotation() const override;
private:
std::vector<ASTPointer<VariableDeclaration>> m_members;
@@ -507,14 +515,14 @@ public:
std::vector<ASTPointer<EnumValue>> const& _members
):
Declaration(_location, _name), m_members(_members) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
std::vector<ASTPointer<EnumValue>> const& members() const { return m_members; }
- virtual TypePointer type() const override;
+ TypePointer type() const override;
- virtual TypeDeclarationAnnotation& annotation() const override;
+ TypeDeclarationAnnotation& annotation() const override;
private:
std::vector<ASTPointer<EnumValue>> m_members;
@@ -529,10 +537,10 @@ public:
EnumValue(SourceLocation const& _location, ASTPointer<ASTString> const& _name):
Declaration(_location, _name) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
- virtual TypePointer type() const override;
+ TypePointer type() const override;
};
/**
@@ -548,8 +556,8 @@ public:
std::vector<ASTPointer<VariableDeclaration>> const& _parameters
):
ASTNode(_location), m_parameters(_parameters) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
std::vector<ASTPointer<VariableDeclaration>> const& parameters() const { return m_parameters; }
@@ -610,8 +618,8 @@ public:
m_body(_body)
{}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
StateMutability stateMutability() const { return m_stateMutability; }
bool isConstructor() const { return m_isConstructor; }
@@ -620,11 +628,11 @@ public:
std::vector<ASTPointer<ModifierInvocation>> const& modifiers() const { return m_functionModifiers; }
std::vector<ASTPointer<VariableDeclaration>> const& returnParameters() const { return m_returnParameters->parameters(); }
Block const& body() const { solAssert(m_body, ""); return *m_body; }
- virtual bool isVisibleInContract() const override
+ bool isVisibleInContract() const override
{
return Declaration::isVisibleInContract() && !isConstructor() && !isFallback();
}
- virtual bool isPartOfExternalInterface() const override { return isPublic() && !isConstructor() && !isFallback(); }
+ bool isPartOfExternalInterface() const override { return isPublic() && !isConstructor() && !isFallback(); }
/// @returns the external signature of the function
/// That consists of the name of the function followed by the types of the
@@ -633,13 +641,13 @@ public:
ContractDefinition::ContractKind inContractKind() const;
- virtual TypePointer type() const override;
+ TypePointer type() const override;
/// @param _internal false indicates external interface is concerned, true indicates internal interface is concerned.
/// @returns null when it is not accessible as a function.
- virtual FunctionTypePointer functionType(bool /*_internal*/) const override;
+ FunctionTypePointer functionType(bool /*_internal*/) const override;
- virtual FunctionDefinitionAnnotation& annotation() const override;
+ FunctionDefinitionAnnotation& annotation() const override;
private:
StateMutability m_stateMutability;
@@ -676,14 +684,14 @@ public:
m_isConstant(_isConstant),
m_location(_referenceLocation) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
TypeName* typeName() const { return m_typeName.get(); }
ASTPointer<Expression> const& value() const { return m_value; }
- virtual bool isLValue() const override;
- virtual bool isPartOfExternalInterface() const override { return isPublic(); }
+ bool isLValue() const override;
+ bool isPartOfExternalInterface() const override { return isPublic(); }
/// @returns true iff this variable is the parameter (or return parameter) of a function
/// (or function type name or event) or declared inside a function body.
@@ -717,13 +725,13 @@ public:
/// @returns a set of allowed storage locations for the variable.
std::set<Location> allowedDataLocations() const;
- virtual TypePointer type() const override;
+ TypePointer type() const override;
/// @param _internal false indicates external interface is concerned, true indicates internal interface is concerned.
/// @returns null when it is not accessible as a function.
- virtual FunctionTypePointer functionType(bool /*_internal*/) const override;
+ FunctionTypePointer functionType(bool /*_internal*/) const override;
- virtual VariableDeclarationAnnotation& annotation() const override;
+ VariableDeclarationAnnotation& annotation() const override;
protected:
Visibility defaultVisibility() const override { return Visibility::Internal; }
@@ -758,14 +766,14 @@ public:
{
}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Block const& body() const { return *m_body; }
- virtual TypePointer type() const override;
+ TypePointer type() const override;
- virtual ModifierDefinitionAnnotation& annotation() const override;
+ ModifierDefinitionAnnotation& annotation() const override;
private:
ASTPointer<Block> m_body;
@@ -784,8 +792,8 @@ public:
):
ASTNode(_location), m_modifierName(_name), m_arguments(std::move(_arguments)) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
ASTPointer<Identifier> const& name() const { return m_modifierName; }
// Returns nullptr if no argument list was given (``mod``).
@@ -817,15 +825,15 @@ public:
{
}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
bool isAnonymous() const { return m_anonymous; }
- virtual TypePointer type() const override;
- virtual FunctionTypePointer functionType(bool /*_internal*/) const override;
+ TypePointer type() const override;
+ FunctionTypePointer functionType(bool /*_internal*/) const override;
- virtual EventDefinitionAnnotation& annotation() const override;
+ EventDefinitionAnnotation& annotation() const override;
private:
bool m_anonymous = false;
@@ -840,21 +848,21 @@ class MagicVariableDeclaration: public Declaration
public:
MagicVariableDeclaration(ASTString const& _name, std::shared_ptr<Type const> const& _type):
Declaration(SourceLocation(), std::make_shared<ASTString>(_name)), m_type(_type) {}
- virtual void accept(ASTVisitor&) override
+ void accept(ASTVisitor&) override
{
solAssert(false, "MagicVariableDeclaration used inside real AST.");
}
- virtual void accept(ASTConstVisitor&) const override
+ void accept(ASTConstVisitor&) const override
{
solAssert(false, "MagicVariableDeclaration used inside real AST.");
}
- virtual FunctionTypePointer functionType(bool) const override
+ FunctionTypePointer functionType(bool) const override
{
solAssert(m_type->category() == Type::Category::Function, "");
return std::dynamic_pointer_cast<FunctionType const>(m_type);
}
- virtual TypePointer type() const override { return m_type; }
+ TypePointer type() const override { return m_type; }
private:
std::shared_ptr<Type const> m_type;
@@ -872,7 +880,7 @@ protected:
explicit TypeName(SourceLocation const& _location): ASTNode(_location) {}
public:
- virtual TypeNameAnnotation& annotation() const override;
+ TypeNameAnnotation& annotation() const override;
};
/**
@@ -891,8 +899,8 @@ public:
solAssert(!_stateMutability.is_initialized() || _elem.token() == Token::Address, "");
}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
ElementaryTypeNameToken const& typeName() const { return m_type; }
@@ -911,12 +919,12 @@ class UserDefinedTypeName: public TypeName
public:
UserDefinedTypeName(SourceLocation const& _location, std::vector<ASTString> const& _namePath):
TypeName(_location), m_namePath(_namePath) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
std::vector<ASTString> const& namePath() const { return m_namePath; }
- virtual UserDefinedTypeNameAnnotation& annotation() const override;
+ UserDefinedTypeNameAnnotation& annotation() const override;
private:
std::vector<ASTString> m_namePath;
@@ -938,8 +946,8 @@ public:
TypeName(_location), m_parameterTypes(_parameterTypes), m_returnTypes(_returnTypes),
m_visibility(_visibility), m_stateMutability(_stateMutability)
{}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
std::vector<ASTPointer<VariableDeclaration>> const& parameterTypes() const { return m_parameterTypes->parameters(); }
std::vector<ASTPointer<VariableDeclaration>> const& returnParameterTypes() const { return m_returnTypes->parameters(); }
@@ -972,8 +980,8 @@ public:
ASTPointer<TypeName> const& _valueType
):
TypeName(_location), m_keyType(_keyType), m_valueType(_valueType) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
ElementaryTypeName const& keyType() const { return *m_keyType; }
TypeName const& valueType() const { return *m_valueType; }
@@ -995,8 +1003,8 @@ public:
ASTPointer<Expression> const& _length
):
TypeName(_location), m_baseType(_baseType), m_length(_length) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
TypeName const& baseType() const { return *m_baseType; }
Expression const* length() const { return m_length.get(); }
@@ -1023,15 +1031,9 @@ public:
ASTPointer<ASTString> const& _docString
): ASTNode(_location), Documented(_docString) {}
- virtual StatementAnnotation& annotation() const override;
+ StatementAnnotation& annotation() const override;
};
-namespace assembly
-{
-// Forward-declaration to AsmData.h
-struct Block;
-}
-
/**
* Inline assembly.
*/
@@ -1041,18 +1043,18 @@ public:
InlineAssembly(
SourceLocation const& _location,
ASTPointer<ASTString> const& _docString,
- std::shared_ptr<assembly::Block> const& _operations
+ std::shared_ptr<yul::Block> const& _operations
):
Statement(_location, _docString), m_operations(_operations) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
- assembly::Block const& operations() const { return *m_operations; }
+ yul::Block const& operations() const { return *m_operations; }
- virtual InlineAssemblyAnnotation& annotation() const override;
+ InlineAssemblyAnnotation& annotation() const override;
private:
- std::shared_ptr<assembly::Block> m_operations;
+ std::shared_ptr<yul::Block> m_operations;
};
/**
@@ -1067,8 +1069,8 @@ public:
std::vector<ASTPointer<Statement>> const& _statements
):
Statement(_location, _docString), m_statements(_statements) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
std::vector<ASTPointer<Statement>> const& statements() const { return m_statements; }
@@ -1088,8 +1090,8 @@ public:
ASTPointer<ASTString> const& _docString
): Statement(_location, _docString) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
};
/**
@@ -1111,8 +1113,8 @@ public:
m_trueBody(_trueBody),
m_falseBody(_falseBody)
{}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Expression const& condition() const { return *m_condition; }
Statement const& trueStatement() const { return *m_trueBody; }
@@ -1149,8 +1151,8 @@ public:
):
BreakableStatement(_location, _docString), m_condition(_condition), m_body(_body),
m_isDoWhile(_isDoWhile) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Expression const& condition() const { return *m_condition; }
Statement const& body() const { return *m_body; }
@@ -1182,8 +1184,8 @@ public:
m_loopExpression(_loopExpression),
m_body(_body)
{}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Statement const* initializationExpression() const { return m_initExpression.get(); }
Expression const* condition() const { return m_condExpression.get(); }
@@ -1206,8 +1208,8 @@ class Continue: public Statement
public:
explicit Continue(SourceLocation const& _location, ASTPointer<ASTString> const& _docString):
Statement(_location, _docString) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
};
class Break: public Statement
@@ -1215,8 +1217,8 @@ class Break: public Statement
public:
explicit Break(SourceLocation const& _location, ASTPointer<ASTString> const& _docString):
Statement(_location, _docString) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
};
class Return: public Statement
@@ -1227,12 +1229,12 @@ public:
ASTPointer<ASTString> const& _docString,
ASTPointer<Expression> _expression
): Statement(_location, _docString), m_expression(_expression) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Expression const* expression() const { return m_expression.get(); }
- virtual ReturnAnnotation& annotation() const override;
+ ReturnAnnotation& annotation() const override;
private:
ASTPointer<Expression> m_expression; ///< value to return, optional
@@ -1246,8 +1248,8 @@ class Throw: public Statement
public:
explicit Throw(SourceLocation const& _location, ASTPointer<ASTString> const& _docString):
Statement(_location, _docString) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
};
/**
@@ -1262,8 +1264,8 @@ public:
ASTPointer<FunctionCall> const& _functionCall
):
Statement(_location, _docString), m_eventCall(_functionCall) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
FunctionCall const& eventCall() const { return *m_eventCall; }
@@ -1289,8 +1291,8 @@ public:
ASTPointer<Expression> const& _initialValue
):
Statement(_location, _docString), m_variables(_variables), m_initialValue(_initialValue) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
std::vector<ASTPointer<VariableDeclaration>> const& declarations() const { return m_variables; }
Expression const* initialValue() const { return m_initialValue.get(); }
@@ -1317,8 +1319,8 @@ public:
ASTPointer<Expression> _expression
):
Statement(_location, _docString), m_expression(_expression) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Expression const& expression() const { return *m_expression; }
@@ -1358,8 +1360,8 @@ public:
m_trueExpression(_trueExpression),
m_falseExpression(_falseExpression)
{}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Expression const& condition() const { return *m_condition; }
Expression const& trueExpression() const { return *m_trueExpression; }
@@ -1389,8 +1391,8 @@ public:
{
solAssert(TokenTraits::isAssignmentOp(_assignmentOperator), "");
}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Expression const& leftHandSide() const { return *m_leftHandSide; }
Token assignmentOperator() const { return m_assigmentOperator; }
@@ -1421,8 +1423,8 @@ public:
Expression(_location),
m_components(_components),
m_isArray(_isArray) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
std::vector<ASTPointer<Expression>> const& components() const { return m_components; }
bool isInlineArray() const { return m_isArray; }
@@ -1452,8 +1454,8 @@ public:
{
solAssert(TokenTraits::isUnaryOp(_operator), "");
}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Token getOperator() const { return m_operator; }
bool isPrefixOperation() const { return m_isPrefix; }
@@ -1482,8 +1484,8 @@ public:
{
solAssert(TokenTraits::isBinaryOp(_operator) || TokenTraits::isCompareOp(_operator), "");
}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Expression const& leftExpression() const { return *m_left; }
Expression const& rightExpression() const { return *m_right; }
@@ -1510,14 +1512,14 @@ public:
std::vector<ASTPointer<ASTString>> const& _names
):
Expression(_location), m_expression(_expression), m_arguments(_arguments), m_names(_names) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Expression const& expression() const { return *m_expression; }
std::vector<ASTPointer<Expression const>> arguments() const { return {m_arguments.begin(), m_arguments.end()}; }
std::vector<ASTPointer<ASTString>> const& names() const { return m_names; }
- virtual FunctionCallAnnotation& annotation() const override;
+ FunctionCallAnnotation& annotation() const override;
private:
ASTPointer<Expression> m_expression;
@@ -1537,8 +1539,8 @@ public:
ASTPointer<TypeName> const& _typeName
):
Expression(_location), m_typeName(_typeName) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
TypeName const& typeName() const { return *m_typeName; }
@@ -1558,12 +1560,12 @@ public:
ASTPointer<ASTString> const& _memberName
):
Expression(_location), m_expression(_expression), m_memberName(_memberName) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Expression const& expression() const { return *m_expression; }
ASTString const& memberName() const { return *m_memberName; }
- virtual MemberAccessAnnotation& annotation() const override;
+ MemberAccessAnnotation& annotation() const override;
private:
ASTPointer<Expression> m_expression;
@@ -1582,8 +1584,8 @@ public:
ASTPointer<Expression> const& _index
):
Expression(_location), m_base(_base), m_index(_index) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Expression const& baseExpression() const { return *m_base; }
Expression const* indexExpression() const { return m_index.get(); }
@@ -1614,12 +1616,12 @@ public:
ASTPointer<ASTString> const& _name
):
PrimaryExpression(_location), m_name(_name) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
ASTString const& name() const { return *m_name; }
- virtual IdentifierAnnotation& annotation() const override;
+ IdentifierAnnotation& annotation() const override;
private:
ASTPointer<ASTString> m_name;
@@ -1636,8 +1638,8 @@ public:
ElementaryTypeNameExpression(SourceLocation const& _location, ElementaryTypeNameToken const& _type):
PrimaryExpression(_location), m_typeToken(_type)
{}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
ElementaryTypeNameToken const& typeName() const { return m_typeToken; }
@@ -1672,8 +1674,8 @@ public:
SubDenomination _sub = SubDenomination::None
):
PrimaryExpression(_location), m_token(_token), m_value(_value), m_subDenomination(_sub) {}
- virtual void accept(ASTVisitor& _visitor) override;
- virtual void accept(ASTConstVisitor& _visitor) const override;
+ void accept(ASTVisitor& _visitor) override;
+ void accept(ASTConstVisitor& _visitor) const override;
Token token() const { return m_token; }
/// @returns the non-parsed value of the literal
diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h
index e0b3f492..e9cc905e 100644
--- a/libsolidity/ast/ASTAnnotations.h
+++ b/libsolidity/ast/ASTAnnotations.h
@@ -30,6 +30,12 @@
#include <vector>
#include <set>
+namespace yul
+{
+ struct AsmAnalysisInfo;
+ struct Identifier;
+}
+
namespace dev
{
namespace solidity
@@ -120,12 +126,6 @@ struct StatementAnnotation: ASTAnnotation, DocumentedAnnotation
{
};
-namespace assembly
-{
- struct AsmAnalysisInfo;
- struct Identifier;
-}
-
struct InlineAssemblyAnnotation: StatementAnnotation
{
struct ExternalIdentifierInfo
@@ -137,9 +137,9 @@ struct InlineAssemblyAnnotation: StatementAnnotation
};
/// Mapping containing resolved references to external identifiers and their value size
- std::map<assembly::Identifier const*, ExternalIdentifierInfo> externalReferences;
+ std::map<yul::Identifier const*, ExternalIdentifierInfo> externalReferences;
/// Information generated during analysis phase.
- std::shared_ptr<assembly::AsmAnalysisInfo> analysisInfo;
+ std::shared_ptr<yul::AsmAnalysisInfo> analysisInfo;
};
struct ReturnAnnotation: StatementAnnotation
diff --git a/libsolidity/ast/ASTEnums.h b/libsolidity/ast/ASTEnums.h
index 5ba21907..d47a5f05 100644
--- a/libsolidity/ast/ASTEnums.h
+++ b/libsolidity/ast/ASTEnums.h
@@ -21,7 +21,7 @@
#pragma once
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <string>
diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp
index 2d26ce8a..b9054692 100644
--- a/libsolidity/ast/ASTJsonConverter.cpp
+++ b/libsolidity/ast/ASTJsonConverter.cpp
@@ -23,10 +23,11 @@
#include <boost/algorithm/string/join.hpp>
#include <libdevcore/UTF8.h>
#include <libsolidity/ast/AST.h>
-#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/inlineasm/AsmPrinter.h>
+#include <libyul/AsmData.h>
+#include <libyul/AsmPrinter.h>
using namespace std;
+using namespace langutil;
namespace dev
{
@@ -171,7 +172,7 @@ void ASTJsonConverter::appendExpressionAttributes(
_attributes += exprAttributes;
}
-Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair<assembly::Identifier const* ,InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const
+Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair<yul::Identifier const* ,InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const
{
Json::Value tuple(Json::objectValue);
tuple["src"] = sourceLocationToString(_info.first->location);
@@ -464,7 +465,7 @@ bool ASTJsonConverter::visit(InlineAssembly const& _node)
}
}
setJsonNode(_node, "InlineAssembly", {
- make_pair("operations", Json::Value(assembly::AsmPrinter()(_node.operations()))),
+ make_pair("operations", Json::Value(yul::AsmPrinter()(_node.operations()))),
make_pair("externalReferences", std::move(externalReferences))
});
return false;
diff --git a/libsolidity/ast/ASTJsonConverter.h b/libsolidity/ast/ASTJsonConverter.h
index 8429708c..ef0a217a 100644
--- a/libsolidity/ast/ASTJsonConverter.h
+++ b/libsolidity/ast/ASTJsonConverter.h
@@ -25,10 +25,15 @@
#include <ostream>
#include <stack>
#include <libsolidity/ast/ASTVisitor.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <libsolidity/ast/ASTAnnotations.h>
#include <json/json.h>
+namespace langutil
+{
+struct SourceLocation;
+}
+
namespace dev
{
namespace solidity
@@ -120,7 +125,7 @@ private:
std::string const& _nodeName,
std::vector<std::pair<std::string, Json::Value>>&& _attributes
);
- std::string sourceLocationToString(SourceLocation const& _location) const;
+ std::string sourceLocationToString(langutil::SourceLocation const& _location) const;
static std::string namePathToString(std::vector<ASTString> const& _namePath);
static Json::Value idOrNull(ASTNode const* _pt)
{
@@ -130,7 +135,7 @@ private:
{
return _node ? toJson(*_node) : Json::nullValue;
}
- Json::Value inlineAssemblyIdentifierToJson(std::pair<assembly::Identifier const* , InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const;
+ Json::Value inlineAssemblyIdentifierToJson(std::pair<yul::Identifier const* , InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const;
static std::string location(VariableDeclaration::Location _location);
static std::string contractKind(ContractDefinition::ContractKind _kind);
static std::string functionCallKind(FunctionCallKind _kind);
diff --git a/libsolidity/ast/ASTPrinter.cpp b/libsolidity/ast/ASTPrinter.cpp
index 255cb9be..cdc6ae7d 100644
--- a/libsolidity/ast/ASTPrinter.cpp
+++ b/libsolidity/ast/ASTPrinter.cpp
@@ -28,6 +28,7 @@
#include <boost/algorithm/string/join.hpp>
using namespace std;
+using namespace langutil;
namespace dev
{
diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h
index 6c0ce6f8..1a761032 100644
--- a/libsolidity/ast/ASTVisitor.h
+++ b/libsolidity/ast/ASTVisitor.h
@@ -262,8 +262,8 @@ public:
): m_onVisit(_onVisit), m_onEndVisit(_onEndVisit) {}
protected:
- virtual bool visitNode(ASTNode const& _n) override { return m_onVisit ? m_onVisit(_n) : true; }
- virtual void endVisitNode(ASTNode const& _n) override { m_onEndVisit(_n); }
+ bool visitNode(ASTNode const& _n) override { return m_onVisit ? m_onVisit(_n) : true; }
+ void endVisitNode(ASTNode const& _n) override { m_onEndVisit(_n); }
private:
std::function<bool(ASTNode const&)> m_onVisit;
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 4b31d2e8..102e43e9 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -45,6 +45,7 @@
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
namespace
@@ -441,10 +442,11 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ContractDefinition
if (!function->isVisibleAsLibraryMember() || seenFunctions.count(function))
continue;
seenFunctions.insert(function);
- FunctionType funType(*function, false);
- if (auto fun = funType.asMemberFunction(true, true))
- if (_type.isImplicitlyConvertibleTo(*fun->selfType()))
- members.push_back(MemberList::Member(function->name(), fun, function));
+ if (function->parameters().empty())
+ continue;
+ FunctionTypePointer fun = FunctionType(*function, false).asCallableFunction(true, true);
+ if (_type.isImplicitlyConvertibleTo(*fun->selfType()))
+ members.push_back(MemberList::Member(function->name(), fun, function));
}
}
return members;
@@ -1969,7 +1971,7 @@ MemberList::MemberMap ContractType::nativeMembers(ContractDefinition const* _con
for (auto const& it: m_contract.interfaceFunctions())
members.push_back(MemberList::Member(
it.second->declaration().name(),
- it.second->asMemberFunction(m_contract.isLibrary()),
+ it.second->asCallableFunction(m_contract.isLibrary()),
&it.second->declaration()
));
}
@@ -3058,10 +3060,10 @@ TypePointer FunctionType::copyAndSetGasOrValue(bool _setGas, bool _setValue) con
);
}
-FunctionTypePointer FunctionType::asMemberFunction(bool _inLibrary, bool _bound) const
+FunctionTypePointer FunctionType::asCallableFunction(bool _inLibrary, bool _bound) const
{
- if (_bound && m_parameterTypes.empty())
- return FunctionTypePointer();
+ if (_bound)
+ solAssert(!m_parameterTypes.empty(), "");
TypePointers parameterTypes;
for (auto const& t: m_parameterTypes)
@@ -3200,7 +3202,7 @@ MemberList::MemberMap TypeType::nativeMembers(ContractDefinition const* _current
if (function->isVisibleAsLibraryMember())
members.push_back(MemberList::Member(
function->name(),
- FunctionType(*function).asMemberFunction(true),
+ FunctionType(*function).asCallableFunction(true),
function
));
if (isBase)
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index 24ace447..953aa557 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -22,7 +22,7 @@
#pragma once
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <libsolidity/ast/ASTForward.h>
#include <libsolidity/ast/ASTEnums.h>
#include <libsolidity/parsing/Token.h>
@@ -331,31 +331,31 @@ public:
static AddressType& address() { static std::shared_ptr<AddressType> addr(std::make_shared<AddressType>(StateMutability::NonPayable)); return *addr; }
static AddressType& addressPayable() { static std::shared_ptr<AddressType> addr(std::make_shared<AddressType>(StateMutability::Payable)); return *addr; }
- virtual Category category() const override { return Category::Address; }
+ Category category() const override { return Category::Address; }
explicit AddressType(StateMutability _stateMutability);
- virtual std::string richIdentifier() const override;
- virtual bool isImplicitlyConvertibleTo(Type const& _other) const override;
- virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual TypePointer unaryOperatorResult(Token _operator) const override;
- virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
+ std::string richIdentifier() const override;
+ bool isImplicitlyConvertibleTo(Type const& _other) const override;
+ bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
+ TypePointer unaryOperatorResult(Token _operator) const override;
+ TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
- virtual bool operator==(Type const& _other) const override;
+ bool operator==(Type const& _other) const override;
- virtual unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : 160 / 8; }
- virtual unsigned storageBytes() const override { return 160 / 8; }
- virtual bool isValueType() const override { return true; }
+ unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : 160 / 8; }
+ unsigned storageBytes() const override { return 160 / 8; }
+ bool isValueType() const override { return true; }
- virtual MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
+ MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
- virtual std::string toString(bool _short) const override;
- virtual std::string canonicalName() const override;
+ std::string toString(bool _short) const override;
+ std::string canonicalName() const override;
- virtual u256 literalValue(Literal const* _literal) const override;
+ u256 literalValue(Literal const* _literal) const override;
- virtual TypePointer encodingType() const override { return shared_from_this(); }
- virtual TypePointer interfaceType(bool) const override { return shared_from_this(); }
+ TypePointer encodingType() const override { return shared_from_this(); }
+ TypePointer interfaceType(bool) const override { return shared_from_this(); }
StateMutability stateMutability(void) const { return m_stateMutability; }
@@ -374,26 +374,26 @@ public:
Unsigned, Signed
};
- virtual Category category() const override { return Category::Integer; }
+ Category category() const override { return Category::Integer; }
explicit IntegerType(unsigned _bits, Modifier _modifier = Modifier::Unsigned);
- virtual std::string richIdentifier() const override;
- virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual TypePointer unaryOperatorResult(Token _operator) const override;
- virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
+ std::string richIdentifier() const override;
+ bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
+ bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
+ TypePointer unaryOperatorResult(Token _operator) const override;
+ TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
- virtual bool operator==(Type const& _other) const override;
+ bool operator==(Type const& _other) const override;
- virtual unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : m_bits / 8; }
- virtual unsigned storageBytes() const override { return m_bits / 8; }
- virtual bool isValueType() const override { return true; }
+ unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : m_bits / 8; }
+ unsigned storageBytes() const override { return m_bits / 8; }
+ bool isValueType() const override { return true; }
- virtual std::string toString(bool _short) const override;
+ std::string toString(bool _short) const override;
- virtual TypePointer encodingType() const override { return shared_from_this(); }
- virtual TypePointer interfaceType(bool) const override { return shared_from_this(); }
+ TypePointer encodingType() const override { return shared_from_this(); }
+ TypePointer interfaceType(bool) const override { return shared_from_this(); }
unsigned numBits() const { return m_bits; }
bool isSigned() const { return m_modifier == Modifier::Signed; }
@@ -416,26 +416,26 @@ public:
{
Unsigned, Signed
};
- virtual Category category() const override { return Category::FixedPoint; }
+ Category category() const override { return Category::FixedPoint; }
explicit FixedPointType(unsigned _totalBits, unsigned _fractionalDigits, Modifier _modifier = Modifier::Unsigned);
- virtual std::string richIdentifier() const override;
- virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual TypePointer unaryOperatorResult(Token _operator) const override;
- virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
+ std::string richIdentifier() const override;
+ bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
+ bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
+ TypePointer unaryOperatorResult(Token _operator) const override;
+ TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
- virtual bool operator==(Type const& _other) const override;
+ bool operator==(Type const& _other) const override;
- virtual unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : m_totalBits / 8; }
- virtual unsigned storageBytes() const override { return m_totalBits / 8; }
- virtual bool isValueType() const override { return true; }
+ unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : m_totalBits / 8; }
+ unsigned storageBytes() const override { return m_totalBits / 8; }
+ bool isValueType() const override { return true; }
- virtual std::string toString(bool _short) const override;
+ std::string toString(bool _short) const override;
- virtual TypePointer encodingType() const override { return shared_from_this(); }
- virtual TypePointer interfaceType(bool) const override { return shared_from_this(); }
+ TypePointer encodingType() const override { return shared_from_this(); }
+ TypePointer interfaceType(bool) const override { return shared_from_this(); }
/// Number of bits used for this type in total.
unsigned numBits() const { return m_totalBits; }
@@ -467,7 +467,7 @@ class RationalNumberType: public Type
{
public:
- virtual Category category() const override { return Category::RationalNumber; }
+ Category category() const override { return Category::RationalNumber; }
static TypePointer forLiteral(Literal const& _literal);
@@ -475,20 +475,20 @@ public:
m_value(_value), m_compatibleBytesType(_compatibleBytesType)
{}
- virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual TypePointer unaryOperatorResult(Token _operator) const override;
- virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
+ bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
+ bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
+ TypePointer unaryOperatorResult(Token _operator) const override;
+ TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
- virtual bool canBeStored() const override { return false; }
- virtual bool canLiveOutsideStorage() const override { return false; }
+ bool canBeStored() const override { return false; }
+ bool canLiveOutsideStorage() const override { return false; }
- virtual std::string toString(bool _short) const override;
- virtual u256 literalValue(Literal const* _literal) const override;
- virtual TypePointer mobileType() const override;
+ std::string toString(bool _short) const override;
+ u256 literalValue(Literal const* _literal) const override;
+ TypePointer mobileType() const override;
/// @returns the smallest integer type that can hold the value or an empty pointer if not possible.
std::shared_ptr<IntegerType const> integerType() const;
@@ -530,25 +530,25 @@ private:
class StringLiteralType: public Type
{
public:
- virtual Category category() const override { return Category::StringLiteral; }
+ Category category() const override { return Category::StringLiteral; }
explicit StringLiteralType(Literal const& _literal);
- virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override
+ bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
+ TypePointer binaryOperatorResult(Token, TypePointer const&) const override
{
return TypePointer();
}
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
- virtual bool canBeStored() const override { return false; }
- virtual bool canLiveOutsideStorage() const override { return false; }
- virtual unsigned sizeOnStack() const override { return 0; }
+ bool canBeStored() const override { return false; }
+ bool canLiveOutsideStorage() const override { return false; }
+ unsigned sizeOnStack() const override { return 0; }
- virtual std::string toString(bool) const override;
- virtual TypePointer mobileType() const override;
+ std::string toString(bool) const override;
+ TypePointer mobileType() const override;
bool isValidUTF8() const;
@@ -564,25 +564,25 @@ private:
class FixedBytesType: public Type
{
public:
- virtual Category category() const override { return Category::FixedBytes; }
+ Category category() const override { return Category::FixedBytes; }
explicit FixedBytesType(unsigned _bytes);
- virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
- virtual TypePointer unaryOperatorResult(Token _operator) const override;
- virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
+ bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
+ bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
+ TypePointer unaryOperatorResult(Token _operator) const override;
+ TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
- virtual unsigned calldataEncodedSize(bool _padded) const override { return _padded && m_bytes > 0 ? 32 : m_bytes; }
- virtual unsigned storageBytes() const override { return m_bytes; }
- virtual bool isValueType() const override { return true; }
+ unsigned calldataEncodedSize(bool _padded) const override { return _padded && m_bytes > 0 ? 32 : m_bytes; }
+ unsigned storageBytes() const override { return m_bytes; }
+ bool isValueType() const override { return true; }
- virtual std::string toString(bool) const override { return "bytes" + dev::toString(m_bytes); }
- virtual MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
- virtual TypePointer encodingType() const override { return shared_from_this(); }
- virtual TypePointer interfaceType(bool) const override { return shared_from_this(); }
+ std::string toString(bool) const override { return "bytes" + dev::toString(m_bytes); }
+ MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
+ TypePointer encodingType() const override { return shared_from_this(); }
+ TypePointer interfaceType(bool) const override { return shared_from_this(); }
unsigned numBytes() const { return m_bytes; }
@@ -597,19 +597,19 @@ class BoolType: public Type
{
public:
BoolType() {}
- virtual Category category() const override { return Category::Bool; }
- virtual std::string richIdentifier() const override { return "t_bool"; }
- virtual TypePointer unaryOperatorResult(Token _operator) const override;
- virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
-
- virtual unsigned calldataEncodedSize(bool _padded) const override{ return _padded ? 32 : 1; }
- virtual unsigned storageBytes() const override { return 1; }
- virtual bool isValueType() const override { return true; }
-
- virtual std::string toString(bool) const override { return "bool"; }
- virtual u256 literalValue(Literal const* _literal) const override;
- virtual TypePointer encodingType() const override { return shared_from_this(); }
- virtual TypePointer interfaceType(bool) const override { return shared_from_this(); }
+ Category category() const override { return Category::Bool; }
+ std::string richIdentifier() const override { return "t_bool"; }
+ TypePointer unaryOperatorResult(Token _operator) const override;
+ TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
+
+ unsigned calldataEncodedSize(bool _padded) const override{ return _padded ? 32 : 1; }
+ unsigned storageBytes() const override { return 1; }
+ bool isValueType() const override { return true; }
+
+ std::string toString(bool) const override { return "bool"; }
+ u256 literalValue(Literal const* _literal) const override;
+ TypePointer encodingType() const override { return shared_from_this(); }
+ TypePointer interfaceType(bool) const override { return shared_from_this(); }
};
/**
@@ -622,20 +622,20 @@ public:
explicit ReferenceType(DataLocation _location): m_location(_location) {}
DataLocation location() const { return m_location; }
- virtual TypePointer unaryOperatorResult(Token _operator) const override;
- virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override
+ TypePointer unaryOperatorResult(Token _operator) const override;
+ TypePointer binaryOperatorResult(Token, TypePointer const&) const override
{
return TypePointer();
}
- virtual unsigned memoryHeadSize() const override { return 32; }
+ unsigned memoryHeadSize() const override { return 32; }
/// @returns a copy of this type with location (recursively) changed to @a _location,
/// whereas isPointer is only shallowly changed - the deep copy is always a bound reference.
virtual TypePointer copyForLocation(DataLocation _location, bool _isPointer) const = 0;
- virtual TypePointer mobileType() const override { return copyForLocation(m_location, true); }
- virtual bool dataStoredIn(DataLocation _location) const override { return m_location == _location; }
- virtual bool hasSimpleZeroValueInMemory() const override { return false; }
+ TypePointer mobileType() const override { return copyForLocation(m_location, true); }
+ bool dataStoredIn(DataLocation _location) const override { return m_location == _location; }
+ bool hasSimpleZeroValueInMemory() const override { return false; }
/// Storage references can be pointers or bound references. In general, local variables are of
/// pointer type, state variables are bound references. Assignments to pointers or deleting
@@ -677,7 +677,7 @@ public:
static ArrayType& bytesMemory() { static std::shared_ptr<ArrayType> addr(std::make_shared<ArrayType>(DataLocation::Memory)); return *addr; }
static ArrayType& stringMemory() { static std::shared_ptr<ArrayType> addr(std::make_shared<ArrayType>(DataLocation::Memory, true)); return *addr; }
- virtual Category category() const override { return Category::Array; }
+ Category category() const override { return Category::Array; }
/// Constructor for a byte array ("bytes") and string.
explicit ArrayType(DataLocation _location, bool _isString = false):
@@ -700,24 +700,24 @@ public:
m_length(_length)
{}
- virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual std::string richIdentifier() const override;
- virtual bool operator==(const Type& _other) const override;
- virtual unsigned calldataEncodedSize(bool _padded) const override;
- virtual bool isDynamicallySized() const override { return m_hasDynamicLength; }
- virtual bool isDynamicallyEncoded() const override;
- virtual u256 storageSize() const override;
- virtual bool canLiveOutsideStorage() const override { return m_baseType->canLiveOutsideStorage(); }
- virtual unsigned sizeOnStack() const override;
- virtual std::string toString(bool _short) const override;
- virtual std::string canonicalName() const override;
- virtual std::string signatureInExternalFunction(bool _structsByName) const override;
- virtual MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
- virtual TypePointer encodingType() const override;
- virtual TypePointer decodingType() const override;
- virtual TypePointer interfaceType(bool _inLibrary) const override;
- virtual bool canBeUsedExternally(bool _inLibrary) const override;
+ bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
+ bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
+ std::string richIdentifier() const override;
+ bool operator==(const Type& _other) const override;
+ unsigned calldataEncodedSize(bool _padded) const override;
+ bool isDynamicallySized() const override { return m_hasDynamicLength; }
+ bool isDynamicallyEncoded() const override;
+ u256 storageSize() const override;
+ bool canLiveOutsideStorage() const override { return m_baseType->canLiveOutsideStorage(); }
+ unsigned sizeOnStack() const override;
+ std::string toString(bool _short) const override;
+ std::string canonicalName() const override;
+ std::string signatureInExternalFunction(bool _structsByName) const override;
+ MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
+ TypePointer encodingType() const override;
+ TypePointer decodingType() const override;
+ TypePointer interfaceType(bool _inLibrary) const override;
+ bool canBeUsedExternally(bool _inLibrary) const override;
/// @returns true if this is valid to be stored in calldata
bool validForCalldata() const;
@@ -751,36 +751,36 @@ private:
class ContractType: public Type
{
public:
- virtual Category category() const override { return Category::Contract; }
+ Category category() const override { return Category::Contract; }
explicit ContractType(ContractDefinition const& _contract, bool _super = false):
m_contract(_contract), m_super(_super) {}
/// Contracts can be implicitly converted only to base contracts.
- virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
+ bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
/// Contracts can only be explicitly converted to address types and base contracts.
- virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual TypePointer unaryOperatorResult(Token _operator) const override;
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
- virtual unsigned calldataEncodedSize(bool _padded ) const override
+ bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
+ TypePointer unaryOperatorResult(Token _operator) const override;
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
+ unsigned calldataEncodedSize(bool _padded ) const override
{
solAssert(!isSuper(), "");
return encodingType()->calldataEncodedSize(_padded);
}
- virtual unsigned storageBytes() const override { solAssert(!isSuper(), ""); return 20; }
- virtual bool canLiveOutsideStorage() const override { return !isSuper(); }
- virtual unsigned sizeOnStack() const override { return m_super ? 0 : 1; }
- virtual bool isValueType() const override { return !isSuper(); }
- virtual std::string toString(bool _short) const override;
- virtual std::string canonicalName() const override;
-
- virtual MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
- virtual TypePointer encodingType() const override
+ unsigned storageBytes() const override { solAssert(!isSuper(), ""); return 20; }
+ bool canLiveOutsideStorage() const override { return !isSuper(); }
+ unsigned sizeOnStack() const override { return m_super ? 0 : 1; }
+ bool isValueType() const override { return !isSuper(); }
+ std::string toString(bool _short) const override;
+ std::string canonicalName() const override;
+
+ MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
+ TypePointer encodingType() const override
{
if (isSuper())
return TypePointer{};
return std::make_shared<AddressType>(isPayable() ? StateMutability::Payable : StateMutability::NonPayable);
}
- virtual TypePointer interfaceType(bool _inLibrary) const override
+ TypePointer interfaceType(bool _inLibrary) const override
{
if (isSuper())
return TypePointer{};
@@ -816,31 +816,31 @@ private:
class StructType: public ReferenceType
{
public:
- virtual Category category() const override { return Category::Struct; }
+ Category category() const override { return Category::Struct; }
explicit StructType(StructDefinition const& _struct, DataLocation _location = DataLocation::Storage):
ReferenceType(_location), m_struct(_struct) {}
- virtual bool isImplicitlyConvertibleTo(const Type& _convertTo) const override;
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
- virtual unsigned calldataEncodedSize(bool _padded) const override;
- virtual bool isDynamicallyEncoded() const override;
+ bool isImplicitlyConvertibleTo(const Type& _convertTo) const override;
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
+ unsigned calldataEncodedSize(bool _padded) const override;
+ bool isDynamicallyEncoded() const override;
u256 memorySize() const;
- virtual u256 storageSize() const override;
- virtual bool canLiveOutsideStorage() const override { return true; }
- virtual std::string toString(bool _short) const override;
+ u256 storageSize() const override;
+ bool canLiveOutsideStorage() const override { return true; }
+ std::string toString(bool _short) const override;
- virtual MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
- virtual TypePointer encodingType() const override
+ MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
+ TypePointer encodingType() const override
{
return location() == DataLocation::Storage ? std::make_shared<IntegerType>(256) : shared_from_this();
}
- virtual TypePointer interfaceType(bool _inLibrary) const override;
- virtual bool canBeUsedExternally(bool _inLibrary) const override;
+ TypePointer interfaceType(bool _inLibrary) const override;
+ bool canBeUsedExternally(bool _inLibrary) const override;
TypePointer copyForLocation(DataLocation _location, bool _isPointer) const override;
- virtual std::string canonicalName() const override;
- virtual std::string signatureInExternalFunction(bool _structsByName) const override;
+ std::string canonicalName() const override;
+ std::string signatureInExternalFunction(bool _structsByName) const override;
/// @returns a function that performs the type conversion between a list of struct members
/// and a memory struct of this type.
@@ -872,27 +872,27 @@ private:
class EnumType: public Type
{
public:
- virtual Category category() const override { return Category::Enum; }
+ Category category() const override { return Category::Enum; }
explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}
- virtual TypePointer unaryOperatorResult(Token _operator) const override;
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
- virtual unsigned calldataEncodedSize(bool _padded) const override
+ TypePointer unaryOperatorResult(Token _operator) const override;
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
+ unsigned calldataEncodedSize(bool _padded) const override
{
return encodingType()->calldataEncodedSize(_padded);
}
- virtual unsigned storageBytes() const override;
- virtual bool canLiveOutsideStorage() const override { return true; }
- virtual std::string toString(bool _short) const override;
- virtual std::string canonicalName() const override;
- virtual bool isValueType() const override { return true; }
-
- virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual TypePointer encodingType() const override
+ unsigned storageBytes() const override;
+ bool canLiveOutsideStorage() const override { return true; }
+ std::string toString(bool _short) const override;
+ std::string canonicalName() const override;
+ bool isValueType() const override { return true; }
+
+ bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
+ TypePointer encodingType() const override
{
return std::make_shared<IntegerType>(8 * int(storageBytes()));
}
- virtual TypePointer interfaceType(bool _inLibrary) const override
+ TypePointer interfaceType(bool _inLibrary) const override
{
return _inLibrary ? shared_from_this() : encodingType();
}
@@ -913,21 +913,21 @@ private:
class TupleType: public Type
{
public:
- virtual Category category() const override { return Category::Tuple; }
+ Category category() const override { return Category::Tuple; }
explicit TupleType(std::vector<TypePointer> const& _types = std::vector<TypePointer>()): m_components(_types) {}
- virtual bool isImplicitlyConvertibleTo(Type const& _other) const override;
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
- virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
- virtual std::string toString(bool) const override;
- virtual bool canBeStored() const override { return false; }
- virtual u256 storageSize() const override;
- virtual bool canLiveOutsideStorage() const override { return false; }
- virtual unsigned sizeOnStack() const override;
- virtual bool hasSimpleZeroValueInMemory() const override { return false; }
- virtual TypePointer mobileType() const override;
+ bool isImplicitlyConvertibleTo(Type const& _other) const override;
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
+ TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
+ std::string toString(bool) const override;
+ bool canBeStored() const override { return false; }
+ u256 storageSize() const override;
+ bool canLiveOutsideStorage() const override { return false; }
+ unsigned sizeOnStack() const override;
+ bool hasSimpleZeroValueInMemory() const override { return false; }
+ TypePointer mobileType() const override;
/// Converts components to their temporary types and performs some wildcard matching.
- virtual TypePointer closestTemporaryType(TypePointer const& _targetType) const override;
+ TypePointer closestTemporaryType(TypePointer const& _targetType) const override;
std::vector<TypePointer> const& components() const { return m_components; }
@@ -987,7 +987,7 @@ public:
GasLeft, ///< gasleft()
};
- virtual Category category() const override { return Category::Function; }
+ Category category() const override { return Category::Function; }
/// Creates the type of a function.
explicit FunctionType(FunctionDefinition const& _function, bool _isInternal = true);
@@ -1061,25 +1061,25 @@ public:
/// @returns the "self" parameter type for a bound function
TypePointer const& selfType() const;
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
- virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
- virtual TypePointer unaryOperatorResult(Token _operator) const override;
- virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override;
- virtual std::string canonicalName() const override;
- virtual std::string toString(bool _short) const override;
- virtual unsigned calldataEncodedSize(bool _padded) const override;
- virtual bool canBeStored() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
- virtual u256 storageSize() const override;
- virtual unsigned storageBytes() const override;
- virtual bool isValueType() const override { return true; }
- virtual bool canLiveOutsideStorage() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
- virtual unsigned sizeOnStack() const override;
- virtual bool hasSimpleZeroValueInMemory() const override { return false; }
- virtual MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
- virtual TypePointer encodingType() const override;
- virtual TypePointer interfaceType(bool _inLibrary) const override;
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
+ bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
+ bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
+ TypePointer unaryOperatorResult(Token _operator) const override;
+ TypePointer binaryOperatorResult(Token, TypePointer const&) const override;
+ std::string canonicalName() const override;
+ std::string toString(bool _short) const override;
+ unsigned calldataEncodedSize(bool _padded) const override;
+ bool canBeStored() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
+ u256 storageSize() const override;
+ unsigned storageBytes() const override;
+ bool isValueType() const override { return true; }
+ bool canLiveOutsideStorage() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
+ unsigned sizeOnStack() const override;
+ bool hasSimpleZeroValueInMemory() const override { return false; }
+ MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
+ TypePointer encodingType() const override;
+ TypePointer interfaceType(bool _inLibrary) const override;
/// @returns TypePointer of a new FunctionType object. All input/return parameters are an
/// appropriate external types (i.e. the interfaceType()s) of input/return parameters of
@@ -1154,14 +1154,13 @@ public:
/// of the parameters to false.
TypePointer copyAndSetGasOrValue(bool _setGas, bool _setValue) const;
- /// @returns a copy of this function type where all return parameters of dynamic size are
- /// removed and the location of reference types is changed from CallData to Memory.
- /// This is needed if external functions are called on other contracts, as they cannot return
- /// dynamic values.
- /// Returns empty shared pointer on a failure. Namely, if a bound function has no parameters.
+ /// @returns a copy of this function type where the location of reference types is changed
+ /// from CallData to Memory. This is the type that would be used when the function is
+ /// called, as opposed to the parameter types that are available inside the function body.
+ /// Also supports variants to be used for library or bound calls.
/// @param _inLibrary if true, uses DelegateCall as location.
- /// @param _bound if true, the arguments are placed as `arg1.functionName(arg2, ..., argn)`.
- FunctionTypePointer asMemberFunction(bool _inLibrary, bool _bound = false) const;
+ /// @param _bound if true, the function type is set to be bound.
+ FunctionTypePointer asCallableFunction(bool _inLibrary, bool _bound = false) const;
private:
static TypePointers parseElementaryTypeVector(strings const& _types);
@@ -1187,27 +1186,27 @@ private:
class MappingType: public Type
{
public:
- virtual Category category() const override { return Category::Mapping; }
+ Category category() const override { return Category::Mapping; }
MappingType(TypePointer const& _keyType, TypePointer const& _valueType):
m_keyType(_keyType), m_valueType(_valueType) {}
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
- virtual std::string toString(bool _short) const override;
- virtual std::string canonicalName() const override;
- virtual bool canLiveOutsideStorage() const override { return false; }
- virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
- virtual TypePointer encodingType() const override
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
+ std::string toString(bool _short) const override;
+ std::string canonicalName() const override;
+ bool canLiveOutsideStorage() const override { return false; }
+ TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
+ TypePointer encodingType() const override
{
return std::make_shared<IntegerType>(256);
}
- virtual TypePointer interfaceType(bool _inLibrary) const override
+ TypePointer interfaceType(bool _inLibrary) const override
{
return _inLibrary ? shared_from_this() : TypePointer();
}
- virtual bool dataStoredIn(DataLocation _location) const override { return _location == DataLocation::Storage; }
+ bool dataStoredIn(DataLocation _location) const override { return _location == DataLocation::Storage; }
/// Cannot be stored in memory, but just in case.
- virtual bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
+ bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
TypePointer const& keyType() const { return m_keyType; }
TypePointer const& valueType() const { return m_valueType; }
@@ -1225,20 +1224,20 @@ private:
class TypeType: public Type
{
public:
- virtual Category category() const override { return Category::TypeType; }
+ Category category() const override { return Category::TypeType; }
explicit TypeType(TypePointer const& _actualType): m_actualType(_actualType) {}
TypePointer const& actualType() const { return m_actualType; }
- virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
- virtual bool canBeStored() const override { return false; }
- virtual u256 storageSize() const override;
- virtual bool canLiveOutsideStorage() const override { return false; }
- virtual unsigned sizeOnStack() const override;
- virtual bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
- virtual std::string toString(bool _short) const override { return "type(" + m_actualType->toString(_short) + ")"; }
- virtual MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
+ TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
+ bool canBeStored() const override { return false; }
+ u256 storageSize() const override;
+ bool canLiveOutsideStorage() const override { return false; }
+ unsigned sizeOnStack() const override;
+ bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
+ std::string toString(bool _short) const override { return "type(" + m_actualType->toString(_short) + ")"; }
+ MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
private:
TypePointer m_actualType;
@@ -1251,18 +1250,18 @@ private:
class ModifierType: public Type
{
public:
- virtual Category category() const override { return Category::Modifier; }
+ Category category() const override { return Category::Modifier; }
explicit ModifierType(ModifierDefinition const& _modifier);
- virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
- virtual bool canBeStored() const override { return false; }
- virtual u256 storageSize() const override;
- virtual bool canLiveOutsideStorage() const override { return false; }
- virtual unsigned sizeOnStack() const override { return 0; }
- virtual bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
- virtual std::string toString(bool _short) const override;
+ TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
+ bool canBeStored() const override { return false; }
+ u256 storageSize() const override;
+ bool canLiveOutsideStorage() const override { return false; }
+ unsigned sizeOnStack() const override { return 0; }
+ bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
+ std::string toString(bool _short) const override;
private:
TypePointers m_parameterTypes;
@@ -1276,20 +1275,20 @@ private:
class ModuleType: public Type
{
public:
- virtual Category category() const override { return Category::Module; }
+ Category category() const override { return Category::Module; }
explicit ModuleType(SourceUnit const& _source): m_sourceUnit(_source) {}
- virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
- virtual bool canBeStored() const override { return false; }
- virtual bool canLiveOutsideStorage() const override { return true; }
- virtual bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
- virtual unsigned sizeOnStack() const override { return 0; }
- virtual MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
+ TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
+ bool canBeStored() const override { return false; }
+ bool canLiveOutsideStorage() const override { return true; }
+ bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
+ unsigned sizeOnStack() const override { return 0; }
+ MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
- virtual std::string toString(bool _short) const override;
+ std::string toString(bool _short) const override;
private:
SourceUnit const& m_sourceUnit;
@@ -1303,24 +1302,24 @@ class MagicType: public Type
{
public:
enum class Kind { Block, Message, Transaction, ABI };
- virtual Category category() const override { return Category::Magic; }
+ Category category() const override { return Category::Magic; }
explicit MagicType(Kind _kind): m_kind(_kind) {}
- virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override
+ TypePointer binaryOperatorResult(Token, TypePointer const&) const override
{
return TypePointer();
}
- virtual std::string richIdentifier() const override;
- virtual bool operator==(Type const& _other) const override;
- virtual bool canBeStored() const override { return false; }
- virtual bool canLiveOutsideStorage() const override { return true; }
- virtual bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
- virtual unsigned sizeOnStack() const override { return 0; }
- virtual MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
+ std::string richIdentifier() const override;
+ bool operator==(Type const& _other) const override;
+ bool canBeStored() const override { return false; }
+ bool canLiveOutsideStorage() const override { return true; }
+ bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
+ unsigned sizeOnStack() const override { return 0; }
+ MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
- virtual std::string toString(bool _short) const override;
+ std::string toString(bool _short) const override;
Kind kind() const { return m_kind; }
@@ -1335,20 +1334,20 @@ private:
class InaccessibleDynamicType: public Type
{
public:
- virtual Category category() const override { return Category::InaccessibleDynamic; }
-
- virtual std::string richIdentifier() const override { return "t_inaccessible"; }
- virtual bool isImplicitlyConvertibleTo(Type const&) const override { return false; }
- virtual bool isExplicitlyConvertibleTo(Type const&) const override { return false; }
- virtual TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
- virtual unsigned calldataEncodedSize(bool _padded) const override { (void)_padded; return 32; }
- virtual bool canBeStored() const override { return false; }
- virtual bool canLiveOutsideStorage() const override { return false; }
- virtual bool isValueType() const override { return true; }
- virtual unsigned sizeOnStack() const override { return 1; }
- virtual bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
- virtual std::string toString(bool) const override { return "inaccessible dynamic type"; }
- virtual TypePointer decodingType() const override { return std::make_shared<IntegerType>(256); }
+ Category category() const override { return Category::InaccessibleDynamic; }
+
+ std::string richIdentifier() const override { return "t_inaccessible"; }
+ bool isImplicitlyConvertibleTo(Type const&) const override { return false; }
+ bool isExplicitlyConvertibleTo(Type const&) const override { return false; }
+ TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
+ unsigned calldataEncodedSize(bool _padded) const override { (void)_padded; return 32; }
+ bool canBeStored() const override { return false; }
+ bool canLiveOutsideStorage() const override { return false; }
+ bool isValueType() const override { return true; }
+ unsigned sizeOnStack() const override { return 1; }
+ bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
+ std::string toString(bool) const override { return "inaccessible dynamic type"; }
+ TypePointer decodingType() const override { return std::make_shared<IntegerType>(256); }
};
}
diff --git a/libsolidity/codegen/ABIFunctions.h b/libsolidity/codegen/ABIFunctions.h
index e9ffe4fb..d2132258 100644
--- a/libsolidity/codegen/ABIFunctions.h
+++ b/libsolidity/codegen/ABIFunctions.h
@@ -22,7 +22,7 @@
#pragma once
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <libsolidity/ast/ASTForward.h>
diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp
index d33f749c..4878f9f3 100644
--- a/libsolidity/codegen/ArrayUtils.cpp
+++ b/libsolidity/codegen/ArrayUtils.cpp
@@ -25,11 +25,12 @@
#include <libsolidity/codegen/CompilerContext.h>
#include <libsolidity/codegen/CompilerUtils.h>
#include <libsolidity/ast/Types.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <libsolidity/codegen/LValue.h>
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace solidity;
void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType const& _sourceType) const
diff --git a/libsolidity/codegen/Compiler.h b/libsolidity/codegen/Compiler.h
index 4028ae63..48d9e9d6 100644
--- a/libsolidity/codegen/Compiler.h
+++ b/libsolidity/codegen/Compiler.h
@@ -23,7 +23,7 @@
#pragma once
#include <libsolidity/codegen/CompilerContext.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <libevmasm/Assembly.h>
diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp
index 6e14d68a..2fd62de2 100644
--- a/libsolidity/codegen/CompilerContext.cpp
+++ b/libsolidity/codegen/CompilerContext.cpp
@@ -25,14 +25,14 @@
#include <libsolidity/ast/AST.h>
#include <libsolidity/codegen/Compiler.h>
#include <libsolidity/interface/Version.h>
-#include <libsolidity/interface/ErrorReporter.h>
-#include <libsolidity/interface/SourceReferenceFormatter.h>
-#include <libsolidity/parsing/Scanner.h>
-#include <libsolidity/inlineasm/AsmParser.h>
-#include <libsolidity/inlineasm/AsmCodeGen.h>
-#include <libsolidity/inlineasm/AsmAnalysis.h>
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
+#include <liblangutil/SourceReferenceFormatter.h>
+#include <libyul/AsmParser.h>
+#include <libyul/AsmCodeGen.h>
+#include <libyul/AsmAnalysis.h>
+#include <libyul/AsmAnalysisInfo.h>
#include <libyul/YulString.h>
+#include <liblangutil/ErrorReporter.h>
+#include <liblangutil/Scanner.h>
#include <boost/algorithm/string/replace.hpp>
@@ -42,11 +42,12 @@
// Change to "define" to output all intermediate code
#undef SOL_OUTPUT_ASM
#ifdef SOL_OUTPUT_ASM
-#include <libsolidity/inlineasm/AsmPrinter.h>
+#include <libyul/AsmPrinter.h>
#endif
using namespace std;
+using namespace langutil;
namespace dev
{
@@ -322,7 +323,7 @@ void CompilerContext::appendInlineAssembly(
yul::ExternalIdentifierAccess identifierAccess;
identifierAccess.resolve = [&](
- assembly::Identifier const& _identifier,
+ yul::Identifier const& _identifier,
yul::IdentifierContext,
bool
)
@@ -331,7 +332,7 @@ void CompilerContext::appendInlineAssembly(
return it == _localVariables.end() ? size_t(-1) : 1;
};
identifierAccess.generateCode = [&](
- assembly::Identifier const& _identifier,
+ yul::Identifier const& _identifier,
yul::IdentifierContext _context,
yul::AbstractAssembly& _assembly
)
@@ -359,20 +360,20 @@ void CompilerContext::appendInlineAssembly(
ErrorList errors;
ErrorReporter errorReporter(errors);
- auto scanner = make_shared<Scanner>(CharStream(_assembly), "--CODEGEN--");
- auto parserResult = assembly::Parser(errorReporter, assembly::AsmFlavour::Strict).parse(scanner, false);
+ auto scanner = make_shared<langutil::Scanner>(langutil::CharStream(_assembly), "--CODEGEN--");
+ auto parserResult = yul::Parser(errorReporter, yul::AsmFlavour::Strict).parse(scanner, false);
#ifdef SOL_OUTPUT_ASM
- cout << assembly::AsmPrinter()(*parserResult) << endl;
+ cout << yul::AsmPrinter()(*parserResult) << endl;
#endif
- assembly::AsmAnalysisInfo analysisInfo;
+ yul::AsmAnalysisInfo analysisInfo;
bool analyzerResult = false;
if (parserResult)
- analyzerResult = assembly::AsmAnalyzer(
+ analyzerResult = yul::AsmAnalyzer(
analysisInfo,
errorReporter,
m_evmVersion,
boost::none,
- assembly::AsmFlavour::Strict,
+ yul::AsmFlavour::Strict,
identifierAccess.resolve
).analyze(*parserResult);
if (!parserResult || !errorReporter.errors().empty() || !analyzerResult)
@@ -394,7 +395,7 @@ void CompilerContext::appendInlineAssembly(
}
solAssert(errorReporter.errors().empty(), "Failed to analyze inline assembly block.");
- assembly::CodeGenerator::assemble(*parserResult, analysisInfo, *m_asm, identifierAccess, _system);
+ yul::CodeGenerator::assemble(*parserResult, analysisInfo, *m_asm, identifierAccess, _system);
// Reset the source location to the one of the node (instead of the CODEGEN source location)
updateSourceLocation();
@@ -413,7 +414,7 @@ FunctionDefinition const& CompilerContext::resolveVirtualFunction(
if (
function->name() == name &&
!function->isConstructor() &&
- FunctionType(*function).hasEqualParameterTypes(functionType)
+ FunctionType(*function).asCallableFunction(false)->hasEqualParameterTypes(functionType)
)
return *function;
solAssert(false, "Super function " + name + " not found.");
diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h
index 5bdc1d19..63365175 100644
--- a/libsolidity/codegen/CompilerContext.h
+++ b/libsolidity/codegen/CompilerContext.h
@@ -24,7 +24,7 @@
#include <libsolidity/codegen/ABIFunctions.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <libsolidity/ast/ASTForward.h>
#include <libsolidity/ast/Types.h>
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index a0d11017..93c8cc77 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -32,6 +32,7 @@
#include <libdevcore/Whiskers.h>
using namespace std;
+using namespace langutil;
namespace dev
{
diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp
index 1fdf3483..157d5fa7 100644
--- a/libsolidity/codegen/ContractCompiler.cpp
+++ b/libsolidity/codegen/ContractCompiler.cpp
@@ -21,11 +21,11 @@
*/
#include <libsolidity/codegen/ContractCompiler.h>
-#include <libsolidity/inlineasm/AsmCodeGen.h>
-#include <libsolidity/ast/AST.h>
-#include <libsolidity/interface/ErrorReporter.h>
#include <libsolidity/codegen/ExpressionCompiler.h>
#include <libsolidity/codegen/CompilerUtils.h>
+#include <libsolidity/ast/AST.h>
+#include <libyul/AsmCodeGen.h>
+#include <liblangutil/ErrorReporter.h>
#include <libevmasm/Instruction.h>
#include <libevmasm/Assembly.h>
@@ -37,6 +37,7 @@
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
namespace
@@ -495,14 +496,14 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
{
unsigned startStackHeight = m_context.stackHeight();
yul::ExternalIdentifierAccess identifierAccess;
- identifierAccess.resolve = [&](assembly::Identifier const& _identifier, yul::IdentifierContext, bool)
+ identifierAccess.resolve = [&](yul::Identifier const& _identifier, yul::IdentifierContext, bool)
{
auto ref = _inlineAssembly.annotation().externalReferences.find(&_identifier);
if (ref == _inlineAssembly.annotation().externalReferences.end())
return size_t(-1);
return ref->second.valueSize;
};
- identifierAccess.generateCode = [&](assembly::Identifier const& _identifier, yul::IdentifierContext _context, yul::AbstractAssembly& _assembly)
+ identifierAccess.generateCode = [&](yul::Identifier const& _identifier, yul::IdentifierContext _context, yul::AbstractAssembly& _assembly)
{
auto ref = _inlineAssembly.annotation().externalReferences.find(&_identifier);
solAssert(ref != _inlineAssembly.annotation().externalReferences.end(), "");
@@ -614,7 +615,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
}
};
solAssert(_inlineAssembly.annotation().analysisInfo, "");
- assembly::CodeGenerator::assemble(
+ yul::CodeGenerator::assemble(
_inlineAssembly.operations(),
*_inlineAssembly.annotation().analysisInfo,
m_context.nonConstAssembly(),
diff --git a/libsolidity/codegen/ContractCompiler.h b/libsolidity/codegen/ContractCompiler.h
index 5fa650b1..001aec7c 100644
--- a/libsolidity/codegen/ContractCompiler.h
+++ b/libsolidity/codegen/ContractCompiler.h
@@ -88,22 +88,22 @@ private:
void registerStateVariables(ContractDefinition const& _contract);
void initializeStateVariables(ContractDefinition const& _contract);
- virtual bool visit(VariableDeclaration const& _variableDeclaration) override;
- virtual bool visit(FunctionDefinition const& _function) override;
- virtual bool visit(InlineAssembly const& _inlineAssembly) override;
- virtual bool visit(IfStatement const& _ifStatement) override;
- virtual bool visit(WhileStatement const& _whileStatement) override;
- virtual bool visit(ForStatement const& _forStatement) override;
- virtual bool visit(Continue const& _continueStatement) override;
- virtual bool visit(Break const& _breakStatement) override;
- virtual bool visit(Return const& _return) override;
- virtual bool visit(Throw const& _throw) override;
- virtual bool visit(EmitStatement const& _emit) override;
- virtual bool visit(VariableDeclarationStatement const& _variableDeclarationStatement) override;
- virtual bool visit(ExpressionStatement const& _expressionStatement) override;
- virtual bool visit(PlaceholderStatement const&) override;
- virtual bool visit(Block const& _block) override;
- virtual void endVisit(Block const& _block) override;
+ bool visit(VariableDeclaration const& _variableDeclaration) override;
+ bool visit(FunctionDefinition const& _function) override;
+ bool visit(InlineAssembly const& _inlineAssembly) override;
+ bool visit(IfStatement const& _ifStatement) override;
+ bool visit(WhileStatement const& _whileStatement) override;
+ bool visit(ForStatement const& _forStatement) override;
+ bool visit(Continue const& _continueStatement) override;
+ bool visit(Break const& _breakStatement) override;
+ bool visit(Return const& _return) override;
+ bool visit(Throw const& _throw) override;
+ bool visit(EmitStatement const& _emit) override;
+ bool visit(VariableDeclarationStatement const& _variableDeclarationStatement) override;
+ bool visit(ExpressionStatement const& _expressionStatement) override;
+ bool visit(PlaceholderStatement const&) override;
+ bool visit(Block const& _block) override;
+ void endVisit(Block const& _block) override;
/// Repeatedly visits all function which are referenced but which are not compiled yet.
void appendMissingFunctions();
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index bdf91fbf..b0d17286 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -36,6 +36,7 @@
#include <libdevcore/Whiskers.h>
using namespace std;
+using namespace langutil;
namespace dev
{
@@ -528,6 +529,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
{
bool shortcutTaken = false;
if (auto identifier = dynamic_cast<Identifier const*>(&_functionCall.expression()))
+ {
+ solAssert(!function.bound(), "");
if (auto functionDef = dynamic_cast<FunctionDefinition const*>(identifier->annotation().referencedDeclaration))
{
// Do not directly visit the identifier, because this way, we can avoid
@@ -536,6 +539,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
utils().pushCombinedFunctionEntryLabel(m_context.resolveVirtualFunction(*functionDef), false);
shortcutTaken = true;
}
+ }
if (!shortcutTaken)
_functionCall.expression().accept(*this);
diff --git a/libsolidity/codegen/ExpressionCompiler.h b/libsolidity/codegen/ExpressionCompiler.h
index 3d8e8682..2bfaab43 100644
--- a/libsolidity/codegen/ExpressionCompiler.h
+++ b/libsolidity/codegen/ExpressionCompiler.h
@@ -25,10 +25,10 @@
#include <memory>
#include <boost/noncopyable.hpp>
#include <libdevcore/Common.h>
-#include <libevmasm/SourceLocation.h>
+#include <liblangutil/SourceLocation.h>
#include <libsolidity/ast/ASTVisitor.h>
#include <libsolidity/codegen/LValue.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
namespace dev {
namespace eth
@@ -71,17 +71,17 @@ public:
void appendConstStateVariableAccessor(const VariableDeclaration& _varDecl);
private:
- virtual bool visit(Conditional const& _condition) override;
- virtual bool visit(Assignment const& _assignment) override;
- virtual bool visit(TupleExpression const& _tuple) override;
- virtual bool visit(UnaryOperation const& _unaryOperation) override;
- virtual bool visit(BinaryOperation const& _binaryOperation) override;
- virtual bool visit(FunctionCall const& _functionCall) override;
- virtual bool visit(NewExpression const& _newExpression) override;
- virtual bool visit(MemberAccess const& _memberAccess) override;
- virtual bool visit(IndexAccess const& _indexAccess) override;
- virtual void endVisit(Identifier const& _identifier) override;
- virtual void endVisit(Literal const& _literal) override;
+ bool visit(Conditional const& _condition) override;
+ bool visit(Assignment const& _assignment) override;
+ bool visit(TupleExpression const& _tuple) override;
+ bool visit(UnaryOperation const& _unaryOperation) override;
+ bool visit(BinaryOperation const& _binaryOperation) override;
+ bool visit(FunctionCall const& _functionCall) override;
+ bool visit(NewExpression const& _newExpression) override;
+ bool visit(MemberAccess const& _memberAccess) override;
+ bool visit(IndexAccess const& _indexAccess) override;
+ void endVisit(Identifier const& _identifier) override;
+ void endVisit(Literal const& _literal) override;
///@{
///@name Append code for various operator types
diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp
index 790ab309..6d71d36f 100644
--- a/libsolidity/codegen/LValue.cpp
+++ b/libsolidity/codegen/LValue.cpp
@@ -28,6 +28,7 @@
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace solidity;
diff --git a/libsolidity/codegen/LValue.h b/libsolidity/codegen/LValue.h
index c576f9de..d854857b 100644
--- a/libsolidity/codegen/LValue.h
+++ b/libsolidity/codegen/LValue.h
@@ -24,7 +24,7 @@
#include <memory>
#include <vector>
-#include <libevmasm/SourceLocation.h>
+#include <liblangutil/SourceLocation.h>
#include <libsolidity/codegen/ArrayUtils.h>
namespace dev
@@ -55,17 +55,17 @@ public:
/// Copies the value of the current lvalue to the top of the stack and, if @a _remove is true,
/// also removes the reference from the stack.
/// @a _location source location of the current expression, used for error reporting.
- virtual void retrieveValue(SourceLocation const& _location, bool _remove = false) const = 0;
+ virtual void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const = 0;
/// Moves a value from the stack to the lvalue. Removes the value if @a _move is true.
/// @a _location is the source location of the expression that caused this operation.
/// Stack pre: value [lvalue_ref]
/// Stack post: if !_move: value_of(lvalue_ref)
virtual void storeValue(Type const& _sourceType,
- SourceLocation const& _location = SourceLocation(), bool _move = false) const = 0;
+ langutil::SourceLocation const& _location = {}, bool _move = false) const = 0;
/// Stores zero in the lvalue. Removes the reference from the stack if @a _removeReference is true.
/// @a _location is the source location of the requested operation
virtual void setToZero(
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const = 0;
@@ -82,15 +82,15 @@ class StackVariable: public LValue
public:
StackVariable(CompilerContext& _compilerContext, VariableDeclaration const& _declaration);
- virtual unsigned sizeOnStack() const override { return 0; }
- virtual void retrieveValue(SourceLocation const& _location, bool _remove = false) const override;
+ unsigned sizeOnStack() const override { return 0; }
+ void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;
virtual void storeValue(
Type const& _sourceType,
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _move = false
) const override;
virtual void setToZero(
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const override;
@@ -108,15 +108,15 @@ class MemoryItem: public LValue
{
public:
MemoryItem(CompilerContext& _compilerContext, Type const& _type, bool _padded = true);
- virtual unsigned sizeOnStack() const override { return 1; }
- virtual void retrieveValue(SourceLocation const& _location, bool _remove = false) const override;
+ unsigned sizeOnStack() const override { return 1; }
+ void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;
virtual void storeValue(
Type const& _sourceType,
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _move = false
) const override;
virtual void setToZero(
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const override;
private:
@@ -136,15 +136,15 @@ public:
StorageItem(CompilerContext& _compilerContext, VariableDeclaration const& _declaration);
/// Constructs the LValue and assumes that the storage reference is already on the stack.
StorageItem(CompilerContext& _compilerContext, Type const& _type);
- virtual unsigned sizeOnStack() const override { return 2; }
- virtual void retrieveValue(SourceLocation const& _location, bool _remove = false) const override;
+ unsigned sizeOnStack() const override { return 2; }
+ void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;
virtual void storeValue(
Type const& _sourceType,
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _move = false
) const override;
virtual void setToZero(
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const override;
};
@@ -158,15 +158,15 @@ class StorageByteArrayElement: public LValue
public:
/// Constructs the LValue and assumes that the storage reference is already on the stack.
StorageByteArrayElement(CompilerContext& _compilerContext);
- virtual unsigned sizeOnStack() const override { return 2; }
- virtual void retrieveValue(SourceLocation const& _location, bool _remove = false) const override;
+ unsigned sizeOnStack() const override { return 2; }
+ void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;
virtual void storeValue(
Type const& _sourceType,
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _move = false
) const override;
virtual void setToZero(
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const override;
};
@@ -181,14 +181,14 @@ class StorageArrayLength: public LValue
public:
/// Constructs the LValue, assumes that the reference to the array head is already on the stack.
StorageArrayLength(CompilerContext& _compilerContext, ArrayType const& _arrayType);
- virtual void retrieveValue(SourceLocation const& _location, bool _remove = false) const override;
+ void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;
virtual void storeValue(
Type const& _sourceType,
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _move = false
) const override;
virtual void setToZero(
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const override;
@@ -205,15 +205,15 @@ public:
/// Constructs the LValue assuming that the other LValues are present on the stack.
/// Empty unique_ptrs are possible if e.g. some values should be ignored during assignment.
TupleObject(CompilerContext& _compilerContext, std::vector<std::unique_ptr<LValue>>&& _lvalues);
- virtual unsigned sizeOnStack() const override;
- virtual void retrieveValue(SourceLocation const& _location, bool _remove = false) const override;
+ unsigned sizeOnStack() const override;
+ void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;
virtual void storeValue(
Type const& _sourceType,
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _move = false
) const override;
virtual void setToZero(
- SourceLocation const& _location = SourceLocation(),
+ langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const override;
diff --git a/libsolidity/formal/CVC4Interface.cpp b/libsolidity/formal/CVC4Interface.cpp
index 6cb91483..de5e4430 100644
--- a/libsolidity/formal/CVC4Interface.cpp
+++ b/libsolidity/formal/CVC4Interface.cpp
@@ -17,7 +17,7 @@
#include <libsolidity/formal/CVC4Interface.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <libdevcore/CommonIO.h>
@@ -33,8 +33,7 @@ CVC4Interface::CVC4Interface():
void CVC4Interface::reset()
{
- m_constants.clear();
- m_functions.clear();
+ m_variables.clear();
m_solver.reset();
m_solver.setOption("produce-models", true);
m_solver.setTimeLimit(queryTimeout);
@@ -50,25 +49,10 @@ void CVC4Interface::pop()
m_solver.pop();
}
-void CVC4Interface::declareFunction(string _name, Sort _domain, Sort _codomain)
+void CVC4Interface::declareVariable(string const& _name, Sort const& _sort)
{
- if (!m_functions.count(_name))
- {
- CVC4::Type fType = m_context.mkFunctionType(cvc4Sort(_domain), cvc4Sort(_codomain));
- m_functions.insert({_name, m_context.mkVar(_name.c_str(), fType)});
- }
-}
-
-void CVC4Interface::declareInteger(string _name)
-{
- if (!m_constants.count(_name))
- m_constants.insert({_name, m_context.mkVar(_name.c_str(), m_context.integerType())});
-}
-
-void CVC4Interface::declareBool(string _name)
-{
- if (!m_constants.count(_name))
- m_constants.insert({_name, m_context.mkVar(_name.c_str(), m_context.booleanType())});
+ if (!m_variables.count(_name))
+ m_variables.insert({_name, m_context.mkVar(_name.c_str(), cvc4Sort(_sort))});
}
void CVC4Interface::addAssertion(Expression const& _expr)
@@ -129,20 +113,19 @@ pair<CheckResult, vector<string>> CVC4Interface::check(vector<Expression> const&
CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
{
- if (_expr.arguments.empty() && m_constants.count(_expr.name))
- return m_constants.at(_expr.name);
+ // Variable
+ if (_expr.arguments.empty() && m_variables.count(_expr.name))
+ return m_variables.at(_expr.name);
+
vector<CVC4::Expr> arguments;
for (auto const& arg: _expr.arguments)
arguments.push_back(toCVC4Expr(arg));
string const& n = _expr.name;
- if (m_functions.count(n))
- return m_context.mkExpr(CVC4::kind::APPLY_UF, m_functions[n], arguments);
- else if (m_constants.count(n))
- {
- solAssert(arguments.empty(), "");
- return m_constants.at(n);
- }
+ // Function application
+ if (!arguments.empty() && m_variables.count(_expr.name))
+ return m_context.mkExpr(CVC4::kind::APPLY_UF, m_variables.at(n), arguments);
+ // Literal
else if (arguments.empty())
{
if (n == "true")
@@ -181,19 +164,33 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
return m_context.mkExpr(CVC4::kind::MULT, arguments[0], arguments[1]);
else if (n == "/")
return m_context.mkExpr(CVC4::kind::INTS_DIVISION_TOTAL, arguments[0], arguments[1]);
+ else if (n == "select")
+ return m_context.mkExpr(CVC4::kind::SELECT, arguments[0], arguments[1]);
+ else if (n == "store")
+ return m_context.mkExpr(CVC4::kind::STORE, arguments[0], arguments[1], arguments[2]);
// Cannot reach here.
solAssert(false, "");
return arguments[0];
}
-CVC4::Type CVC4Interface::cvc4Sort(Sort _sort)
+CVC4::Type CVC4Interface::cvc4Sort(Sort const& _sort)
{
- switch (_sort)
+ switch (_sort.kind)
{
- case Sort::Bool:
+ case Kind::Bool:
return m_context.booleanType();
- case Sort::Int:
+ case Kind::Int:
return m_context.integerType();
+ case Kind::Function:
+ {
+ FunctionSort const& fSort = dynamic_cast<FunctionSort const&>(_sort);
+ return m_context.mkFunctionType(cvc4Sort(fSort.domain), cvc4Sort(*fSort.codomain));
+ }
+ case Kind::Array:
+ {
+ auto const& arraySort = dynamic_cast<ArraySort const&>(_sort);
+ return m_context.mkArrayType(cvc4Sort(*arraySort.domain), cvc4Sort(*arraySort.range));
+ }
default:
break;
}
@@ -201,3 +198,11 @@ CVC4::Type CVC4Interface::cvc4Sort(Sort _sort)
// Cannot be reached.
return m_context.integerType();
}
+
+vector<CVC4::Type> CVC4Interface::cvc4Sort(vector<SortPointer> const& _sorts)
+{
+ vector<CVC4::Type> cvc4Sorts;
+ for (auto const& _sort: _sorts)
+ cvc4Sorts.push_back(cvc4Sort(*_sort));
+ return cvc4Sorts;
+}
diff --git a/libsolidity/formal/CVC4Interface.h b/libsolidity/formal/CVC4Interface.h
index cd6d761d..bbe23855 100644
--- a/libsolidity/formal/CVC4Interface.h
+++ b/libsolidity/formal/CVC4Interface.h
@@ -51,21 +51,19 @@ public:
void push() override;
void pop() override;
- void declareFunction(std::string _name, Sort _domain, Sort _codomain) override;
- void declareInteger(std::string _name) override;
- void declareBool(std::string _name) override;
+ void declareVariable(std::string const&, Sort const&) override;
void addAssertion(Expression const& _expr) override;
std::pair<CheckResult, std::vector<std::string>> check(std::vector<Expression> const& _expressionsToEvaluate) override;
private:
CVC4::Expr toCVC4Expr(Expression const& _expr);
- CVC4::Type cvc4Sort(smt::Sort _sort);
+ CVC4::Type cvc4Sort(smt::Sort const& _sort);
+ std::vector<CVC4::Type> cvc4Sort(std::vector<smt::SortPointer> const& _sorts);
CVC4::ExprManager m_context;
CVC4::SmtEngine m_solver;
- std::map<std::string, CVC4::Expr> m_constants;
- std::map<std::string, CVC4::Expr> m_functions;
+ std::map<std::string, CVC4::Expr> m_variables;
};
}
diff --git a/libsolidity/formal/SMTChecker.cpp b/libsolidity/formal/SMTChecker.cpp
index cc580021..5b7807f7 100644
--- a/libsolidity/formal/SMTChecker.cpp
+++ b/libsolidity/formal/SMTChecker.cpp
@@ -22,19 +22,29 @@
#include <libsolidity/formal/VariableUsage.h>
#include <libsolidity/formal/SymbolicTypes.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
#include <boost/range/adaptor/map.hpp>
#include <boost/algorithm/string/replace.hpp>
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
-SMTChecker::SMTChecker(ErrorReporter& _errorReporter, ReadCallback::Callback const& _readFileCallback):
- m_interface(make_shared<smt::SMTPortfolio>(_readFileCallback)),
+SMTChecker::SMTChecker(ErrorReporter& _errorReporter, map<h256, string> const& _smtlib2Responses):
+ m_interface(make_shared<smt::SMTPortfolio>(_smtlib2Responses)),
m_errorReporter(_errorReporter)
{
+#if defined (HAVE_Z3) || defined (HAVE_CVC4)
+ if (!_smtlib2Responses.empty())
+ m_errorReporter.warning(
+ "SMT-LIB2 query responses were given in the auxiliary input, "
+ "but this Solidity binary uses an SMT solver (Z3/CVC4) directly."
+ "These responses will be ignored."
+ "Consider disabling Z3/CVC4 at compilation time in order to use SMT-LIB2 responses."
+ );
+#endif
}
void SMTChecker::analyze(SourceUnit const& _source, shared_ptr<Scanner> const& _scanner)
@@ -78,6 +88,9 @@ bool SMTChecker::visit(FunctionDefinition const& _function)
m_interface->reset();
m_pathConditions.clear();
m_expressions.clear();
+ m_specialVariables.clear();
+ m_uninterpretedFunctions.clear();
+ m_uninterpretedTerms.clear();
resetStateVariables();
initializeLocalVariables(_function);
}
@@ -405,16 +418,24 @@ void SMTChecker::visitGasLeft(FunctionCall const& _funCall)
auto const& symbolicVar = m_specialVariables.at(gasLeft);
unsigned index = symbolicVar->index();
// We set the current value to unknown anyway to add type constraints.
- symbolicVar->setUnknownValue();
+ setUnknownValue(*symbolicVar);
if (index > 0)
m_interface->addAssertion(symbolicVar->currentValue() <= symbolicVar->valueAtIndex(index - 1));
}
void SMTChecker::visitBlockHash(FunctionCall const& _funCall)
{
- string blockHash = "blockhash()";
- // TODO Define blockhash as an uninterpreted function
- defineSpecialVariable(blockHash, _funCall);
+ string blockHash = "blockhash";
+ auto const& arguments = _funCall.arguments();
+ solAssert(arguments.size() == 1, "");
+ smt::SortPointer paramSort = smtSort(*arguments.at(0)->annotation().type);
+ smt::SortPointer returnSort = smtSort(*_funCall.annotation().type);
+ defineUninterpretedFunction(
+ blockHash,
+ make_shared<smt::FunctionSort>(vector<smt::SortPointer>{paramSort}, returnSort)
+ );
+ defineExpr(_funCall, m_uninterpretedFunctions.at(blockHash)({expr(*arguments.at(0))}));
+ m_uninterpretedTerms.push_back(&_funCall);
}
void SMTChecker::inlineFunctionCall(FunctionCall const& _funCall)
@@ -451,6 +472,14 @@ void SMTChecker::inlineFunctionCall(FunctionCall const& _funCall)
else if (_funDef && _funDef->isImplemented())
{
vector<smt::Expression> funArgs;
+ auto const& funType = dynamic_cast<FunctionType const*>(_calledExpr->annotation().type.get());
+ solAssert(funType, "");
+ if (funType->bound())
+ {
+ auto const& boundFunction = dynamic_cast<MemberAccess const*>(_calledExpr);
+ solAssert(boundFunction, "");
+ funArgs.push_back(expr(boundFunction->expression()));
+ }
for (auto arg: _funCall.arguments())
funArgs.push_back(expr(*arg));
initializeFunctionCallParameters(*_funDef, funArgs);
@@ -542,6 +571,10 @@ void SMTChecker::endVisit(Return const& _return)
bool SMTChecker::visit(MemberAccess const& _memberAccess)
{
+ auto const& accessType = _memberAccess.annotation().type;
+ if (accessType->category() == Type::Category::Function)
+ return true;
+
auto const& exprType = _memberAccess.expression().annotation().type;
solAssert(exprType, "");
if (exprType->category() == Type::Category::Magic)
@@ -573,7 +606,7 @@ void SMTChecker::defineSpecialVariable(string const& _name, Expression const& _e
{
auto result = newSymbolicVariable(*_expr.annotation().type, _name, *m_interface);
m_specialVariables.emplace(_name, result.second);
- result.second->setUnknownValue();
+ setUnknownValue(*result.second);
if (result.first)
m_errorReporter.warning(
_expr.location(),
@@ -587,6 +620,11 @@ void SMTChecker::defineSpecialVariable(string const& _name, Expression const& _e
defineExpr(_expr, m_specialVariables.at(_name)->currentValue());
}
+void SMTChecker::defineUninterpretedFunction(string const& _name, smt::SortPointer _sort)
+{
+ if (!m_uninterpretedFunctions.count(_name))
+ m_uninterpretedFunctions.emplace(_name, m_interface->newVariable(_name, _sort));
+}
void SMTChecker::arithmeticOperation(BinaryOperation const& _op)
{
@@ -770,6 +808,11 @@ void SMTChecker::checkCondition(
expressionsToEvaluate.emplace_back(var.second->currentValue());
expressionNames.push_back(var.first);
}
+ for (auto const& uf: m_uninterpretedTerms)
+ {
+ expressionsToEvaluate.emplace_back(expr(*uf));
+ expressionNames.push_back(m_scanner->sourceAt(uf->location()));
+ }
}
smt::CheckResult result;
vector<string> values;
@@ -1037,13 +1080,23 @@ smt::Expression SMTChecker::newValue(VariableDeclaration const& _decl)
void SMTChecker::setZeroValue(VariableDeclaration const& _decl)
{
solAssert(knownVariable(_decl), "");
- m_variables.at(&_decl)->setZeroValue();
+ setZeroValue(*m_variables.at(&_decl));
+}
+
+void SMTChecker::setZeroValue(SymbolicVariable& _variable)
+{
+ smt::setSymbolicZeroValue(_variable, *m_interface);
}
void SMTChecker::setUnknownValue(VariableDeclaration const& _decl)
{
solAssert(knownVariable(_decl), "");
- m_variables.at(&_decl)->setUnknownValue();
+ setUnknownValue(*m_variables.at(&_decl));
+}
+
+void SMTChecker::setUnknownValue(SymbolicVariable& _variable)
+{
+ smt::setSymbolicUnknownValue(_variable, *m_interface);
}
smt::Expression SMTChecker::expr(Expression const& _e)
diff --git a/libsolidity/formal/SMTChecker.h b/libsolidity/formal/SMTChecker.h
index a7f955dd..34724848 100644
--- a/libsolidity/formal/SMTChecker.h
+++ b/libsolidity/formal/SMTChecker.h
@@ -25,50 +25,60 @@
#include <libsolidity/interface/ReadFile.h>
-#include <libsolidity/parsing/Scanner.h>
+#include <liblangutil/Scanner.h>
#include <unordered_map>
#include <string>
#include <vector>
+namespace langutil
+{
+class ErrorReporter;
+struct SourceLocation;
+}
+
namespace dev
{
namespace solidity
{
class VariableUsage;
-class ErrorReporter;
class SMTChecker: private ASTConstVisitor
{
public:
- SMTChecker(ErrorReporter& _errorReporter, ReadCallback::Callback const& _readCallback);
+ SMTChecker(langutil::ErrorReporter& _errorReporter, std::map<h256, std::string> const& _smtlib2Responses);
+
+ void analyze(SourceUnit const& _sources, std::shared_ptr<langutil::Scanner> const& _scanner);
- void analyze(SourceUnit const& _sources, std::shared_ptr<Scanner> const& _scanner);
+ /// This is used if the SMT solver is not directly linked into this binary.
+ /// @returns a list of inputs to the SMT solver that were not part of the argument to
+ /// the constructor.
+ std::vector<std::string> unhandledQueries() { return m_interface->unhandledQueries(); }
private:
// TODO: Check that we do not have concurrent reads and writes to a variable,
// because the order of expression evaluation is undefined
// TODO: or just force a certain order, but people might have a different idea about that.
- virtual bool visit(ContractDefinition const& _node) override;
- virtual void endVisit(ContractDefinition const& _node) override;
- virtual void endVisit(VariableDeclaration const& _node) override;
- virtual bool visit(FunctionDefinition const& _node) override;
- virtual void endVisit(FunctionDefinition const& _node) override;
- virtual bool visit(IfStatement const& _node) override;
- virtual bool visit(WhileStatement const& _node) override;
- virtual bool visit(ForStatement const& _node) override;
- virtual void endVisit(VariableDeclarationStatement const& _node) override;
- virtual void endVisit(Assignment const& _node) override;
- virtual void endVisit(TupleExpression const& _node) override;
- virtual void endVisit(UnaryOperation const& _node) override;
- virtual void endVisit(BinaryOperation const& _node) override;
- virtual void endVisit(FunctionCall const& _node) override;
- virtual void endVisit(Identifier const& _node) override;
- virtual void endVisit(Literal const& _node) override;
- virtual void endVisit(Return const& _node) override;
- virtual bool visit(MemberAccess const& _node) override;
+ bool visit(ContractDefinition const& _node) override;
+ void endVisit(ContractDefinition const& _node) override;
+ void endVisit(VariableDeclaration const& _node) override;
+ bool visit(FunctionDefinition const& _node) override;
+ void endVisit(FunctionDefinition const& _node) override;
+ bool visit(IfStatement const& _node) override;
+ bool visit(WhileStatement const& _node) override;
+ bool visit(ForStatement const& _node) override;
+ void endVisit(VariableDeclarationStatement const& _node) override;
+ void endVisit(Assignment const& _node) override;
+ void endVisit(TupleExpression const& _node) override;
+ void endVisit(UnaryOperation const& _node) override;
+ void endVisit(BinaryOperation const& _node) override;
+ void endVisit(FunctionCall const& _node) override;
+ void endVisit(Identifier const& _node) override;
+ void endVisit(Literal const& _node) override;
+ void endVisit(Return const& _node) override;
+ bool visit(MemberAccess const& _node) override;
void arithmeticOperation(BinaryOperation const& _op);
void compareOperation(BinaryOperation const& _op);
@@ -83,13 +93,14 @@ private:
void inlineFunctionCall(FunctionCall const&);
void defineSpecialVariable(std::string const& _name, Expression const& _expr, bool _increaseIndex = false);
+ void defineUninterpretedFunction(std::string const& _name, smt::SortPointer _sort);
/// Division expression in the given type. Requires special treatment because
/// of rounding for signed division.
smt::Expression division(smt::Expression _left, smt::Expression _right, IntegerType const& _type);
- void assignment(VariableDeclaration const& _variable, Expression const& _value, SourceLocation const& _location);
- void assignment(VariableDeclaration const& _variable, smt::Expression const& _value, SourceLocation const& _location);
+ void assignment(VariableDeclaration const& _variable, Expression const& _value, langutil::SourceLocation const& _location);
+ void assignment(VariableDeclaration const& _variable, smt::Expression const& _value, langutil::SourceLocation const& _location);
/// Maps a variable to an SSA index.
using VariableIndices = std::unordered_map<VariableDeclaration const*, int>;
@@ -103,7 +114,7 @@ private:
/// Check that a condition can be satisfied.
void checkCondition(
smt::Expression _condition,
- SourceLocation const& _location,
+ langutil::SourceLocation const& _location,
std::string const& _description,
std::string const& _additionalValueName = "",
smt::Expression* _additionalValue = nullptr
@@ -116,7 +127,7 @@ private:
std::string const& _description
);
/// Checks that the value is in the range given by the type.
- void checkUnderOverflow(smt::Expression _value, IntegerType const& _Type, SourceLocation const& _location);
+ void checkUnderOverflow(smt::Expression _value, IntegerType const& _Type, langutil::SourceLocation const& _location);
std::pair<smt::CheckResult, std::vector<std::string>>
@@ -151,8 +162,10 @@ private:
/// Sets the value of the declaration to zero.
void setZeroValue(VariableDeclaration const& _decl);
+ void setZeroValue(SymbolicVariable& _variable);
/// Resets the variable to an unknown value (in its range).
void setUnknownValue(VariableDeclaration const& decl);
+ void setUnknownValue(SymbolicVariable& _variable);
/// Returns the expression corresponding to the AST node. Throws if the expression does not exist.
smt::Expression expr(Expression const& _e);
@@ -193,9 +206,14 @@ private:
std::unordered_map<Expression const*, std::shared_ptr<SymbolicVariable>> m_expressions;
std::unordered_map<VariableDeclaration const*, std::shared_ptr<SymbolicVariable>> m_variables;
std::unordered_map<std::string, std::shared_ptr<SymbolicVariable>> m_specialVariables;
+ /// Stores the declaration of an Uninterpreted Function.
+ std::unordered_map<std::string, smt::Expression> m_uninterpretedFunctions;
+ /// Stores the instances of an Uninterpreted Function applied to arguments.
+ /// Used to retrieve models.
+ std::vector<Expression const*> m_uninterpretedTerms;
std::vector<smt::Expression> m_pathConditions;
- ErrorReporter& m_errorReporter;
- std::shared_ptr<Scanner> m_scanner;
+ langutil::ErrorReporter& m_errorReporter;
+ std::shared_ptr<langutil::Scanner> m_scanner;
/// Stores the current path of function calls.
std::vector<FunctionDefinition const*> m_functionPath;
diff --git a/libsolidity/formal/SMTLib2Interface.cpp b/libsolidity/formal/SMTLib2Interface.cpp
index a6c1f87c..3cfa01b1 100644
--- a/libsolidity/formal/SMTLib2Interface.cpp
+++ b/libsolidity/formal/SMTLib2Interface.cpp
@@ -17,9 +17,11 @@
#include <libsolidity/formal/SMTLib2Interface.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <libsolidity/interface/ReadFile.h>
+#include <libdevcore/Keccak256.h>
+
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/filesystem/operations.hpp>
@@ -37,8 +39,8 @@ using namespace dev;
using namespace dev::solidity;
using namespace dev::solidity::smt;
-SMTLib2Interface::SMTLib2Interface(ReadCallback::Callback const& _queryCallback):
- m_queryCallback(_queryCallback)
+SMTLib2Interface::SMTLib2Interface(map<h256, string> const& _queryResponses):
+ m_queryResponses(_queryResponses)
{
reset();
}
@@ -47,8 +49,7 @@ void SMTLib2Interface::reset()
{
m_accumulatedOutput.clear();
m_accumulatedOutput.emplace_back();
- m_constants.clear();
- m_functions.clear();
+ m_variables.clear();
write("(set-option :produce-models true)");
write("(set-logic QF_UFLIA)");
}
@@ -64,42 +65,39 @@ void SMTLib2Interface::pop()
m_accumulatedOutput.pop_back();
}
-void SMTLib2Interface::declareFunction(string _name, Sort _domain, Sort _codomain)
+void SMTLib2Interface::declareVariable(string const& _name, Sort const& _sort)
+{
+ if (_sort.kind == Kind::Function)
+ declareFunction(_name, _sort);
+ else if (!m_variables.count(_name))
+ {
+ m_variables.insert(_name);
+ write("(declare-fun |" + _name + "| () " + toSmtLibSort(_sort) + ')');
+ }
+}
+
+void SMTLib2Interface::declareFunction(string const& _name, Sort const& _sort)
{
+ solAssert(_sort.kind == smt::Kind::Function, "");
// TODO Use domain and codomain as key as well
- if (!m_functions.count(_name))
+ if (!m_variables.count(_name))
{
- m_functions.insert(_name);
+ FunctionSort fSort = dynamic_cast<FunctionSort const&>(_sort);
+ string domain = toSmtLibSort(fSort.domain);
+ string codomain = toSmtLibSort(*fSort.codomain);
+ m_variables.insert(_name);
write(
"(declare-fun |" +
_name +
- "| (" +
- (_domain == Sort::Int ? "Int" : "Bool") +
- ") " +
- (_codomain == Sort::Int ? "Int" : "Bool") +
+ "| " +
+ domain +
+ " " +
+ codomain +
")"
);
}
}
-void SMTLib2Interface::declareInteger(string _name)
-{
- if (!m_constants.count(_name))
- {
- m_constants.insert(_name);
- write("(declare-const |" + _name + "| Int)");
- }
-}
-
-void SMTLib2Interface::declareBool(string _name)
-{
- if (!m_constants.count(_name))
- {
- m_constants.insert(_name);
- write("(declare-const |" + _name + "| Bool)");
- }
-}
-
void SMTLib2Interface::addAssertion(Expression const& _expr)
{
write("(assert " + toSExpr(_expr) + ")");
@@ -140,6 +138,33 @@ string SMTLib2Interface::toSExpr(Expression const& _expr)
return sexpr;
}
+string SMTLib2Interface::toSmtLibSort(Sort const& _sort)
+{
+ switch (_sort.kind)
+ {
+ case Kind::Int:
+ return "Int";
+ case Kind::Bool:
+ return "Bool";
+ case Kind::Array:
+ {
+ auto const& arraySort = dynamic_cast<ArraySort const&>(_sort);
+ return "(Array " + toSmtLibSort(*arraySort.domain) + ' ' + toSmtLibSort(*arraySort.range) + ')';
+ }
+ default:
+ solAssert(false, "Invalid SMT sort");
+ }
+}
+
+string SMTLib2Interface::toSmtLibSort(vector<SortPointer> const& _sorts)
+{
+ string ssort("(");
+ for (auto const& sort: _sorts)
+ ssort += toSmtLibSort(*sort) + " ";
+ ssort += ")";
+ return ssort;
+}
+
void SMTLib2Interface::write(string _data)
{
solAssert(!m_accumulatedOutput.empty(), "");
@@ -157,8 +182,8 @@ string SMTLib2Interface::checkSatAndGetValuesCommand(vector<Expression> const& _
for (size_t i = 0; i < _expressionsToEvaluate.size(); i++)
{
auto const& e = _expressionsToEvaluate.at(i);
- solAssert(e.sort == Sort::Int || e.sort == Sort::Bool, "Invalid sort for expression to evaluate.");
- command += "(declare-const |EVALEXPR_" + to_string(i) + "| " + (e.sort == Sort::Int ? "Int" : "Bool") + ")\n";
+ solAssert(e.sort->kind == Kind::Int || e.sort->kind == Kind::Bool, "Invalid sort for expression to evaluate.");
+ command += "(declare-const |EVALEXPR_" + to_string(i) + "| " + (e.sort->kind == Kind::Int ? "Int" : "Bool") + ")\n";
command += "(assert (= |EVALEXPR_" + to_string(i) + "| " + toSExpr(e) + "))\n";
}
command += "(check-sat)\n";
@@ -189,11 +214,12 @@ vector<string> SMTLib2Interface::parseValues(string::const_iterator _start, stri
string SMTLib2Interface::querySolver(string const& _input)
{
- if (!m_queryCallback)
- BOOST_THROW_EXCEPTION(SolverError() << errinfo_comment("No SMT solver available."));
-
- ReadCallback::Result queryResult = m_queryCallback(_input);
- if (!queryResult.success)
- BOOST_THROW_EXCEPTION(SolverError() << errinfo_comment(queryResult.responseOrErrorMessage));
- return queryResult.responseOrErrorMessage;
+ h256 inputHash = dev::keccak256(_input);
+ if (m_queryResponses.count(inputHash))
+ return m_queryResponses.at(inputHash);
+ else
+ {
+ m_unhandledQueries.push_back(_input);
+ return "unknown\n";
+ }
}
diff --git a/libsolidity/formal/SMTLib2Interface.h b/libsolidity/formal/SMTLib2Interface.h
index eb876a7f..55fc4096 100644
--- a/libsolidity/formal/SMTLib2Interface.h
+++ b/libsolidity/formal/SMTLib2Interface.h
@@ -19,9 +19,11 @@
#include <libsolidity/formal/SolverInterface.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <libsolidity/interface/ReadFile.h>
+#include <libdevcore/FixedHash.h>
+
#include <libdevcore/Common.h>
#include <boost/noncopyable.hpp>
@@ -42,22 +44,26 @@ namespace smt
class SMTLib2Interface: public SolverInterface, public boost::noncopyable
{
public:
- explicit SMTLib2Interface(ReadCallback::Callback const& _queryCallback);
+ explicit SMTLib2Interface(std::map<h256, std::string> const& _queryResponses);
void reset() override;
void push() override;
void pop() override;
- void declareFunction(std::string _name, Sort _domain, Sort _codomain) override;
- void declareInteger(std::string _name) override;
- void declareBool(std::string _name) override;
+ void declareVariable(std::string const&, Sort const&) override;
void addAssertion(Expression const& _expr) override;
std::pair<CheckResult, std::vector<std::string>> check(std::vector<Expression> const& _expressionsToEvaluate) override;
+ std::vector<std::string> unhandledQueries() override { return m_unhandledQueries; }
+
private:
+ void declareFunction(std::string const&, Sort const&);
+
std::string toSExpr(Expression const& _expr);
+ std::string toSmtLibSort(Sort const& _sort);
+ std::string toSmtLibSort(std::vector<SortPointer> const& _sort);
void write(std::string _data);
@@ -67,10 +73,11 @@ private:
/// Communicates with the solver via the callback. Throws SMTSolverError on error.
std::string querySolver(std::string const& _input);
- ReadCallback::Callback m_queryCallback;
std::vector<std::string> m_accumulatedOutput;
- std::set<std::string> m_constants;
- std::set<std::string> m_functions;
+ std::set<std::string> m_variables;
+
+ std::map<h256, std::string> const& m_queryResponses;
+ std::vector<std::string> m_unhandledQueries;
};
}
diff --git a/libsolidity/formal/SMTPortfolio.cpp b/libsolidity/formal/SMTPortfolio.cpp
index 8b9fe9ce..2a109b89 100644
--- a/libsolidity/formal/SMTPortfolio.cpp
+++ b/libsolidity/formal/SMTPortfolio.cpp
@@ -23,27 +23,22 @@
#ifdef HAVE_CVC4
#include <libsolidity/formal/CVC4Interface.h>
#endif
-#if !defined (HAVE_Z3) && !defined (HAVE_CVC4)
#include <libsolidity/formal/SMTLib2Interface.h>
-#endif
using namespace std;
using namespace dev;
using namespace dev::solidity;
using namespace dev::solidity::smt;
-SMTPortfolio::SMTPortfolio(ReadCallback::Callback const& _readCallback)
+SMTPortfolio::SMTPortfolio(map<h256, string> const& _smtlib2Responses)
{
+ m_solvers.emplace_back(make_shared<smt::SMTLib2Interface>(_smtlib2Responses));
#ifdef HAVE_Z3
m_solvers.emplace_back(make_shared<smt::Z3Interface>());
#endif
#ifdef HAVE_CVC4
m_solvers.emplace_back(make_shared<smt::CVC4Interface>());
#endif
-#if !defined (HAVE_Z3) && !defined (HAVE_CVC4)
- m_solvers.emplace_back(make_shared<smt::SMTLib2Interface>(_readCallback)),
-#endif
- (void)_readCallback;
}
void SMTPortfolio::reset()
@@ -64,22 +59,10 @@ void SMTPortfolio::pop()
s->pop();
}
-void SMTPortfolio::declareFunction(string _name, Sort _domain, Sort _codomain)
-{
- for (auto s : m_solvers)
- s->declareFunction(_name, _domain, _codomain);
-}
-
-void SMTPortfolio::declareInteger(string _name)
-{
- for (auto s : m_solvers)
- s->declareInteger(_name);
-}
-
-void SMTPortfolio::declareBool(string _name)
+void SMTPortfolio::declareVariable(string const& _name, Sort const& _sort)
{
for (auto s : m_solvers)
- s->declareBool(_name);
+ s->declareVariable(_name, _sort);
}
void SMTPortfolio::addAssertion(Expression const& _expr)
diff --git a/libsolidity/formal/SMTPortfolio.h b/libsolidity/formal/SMTPortfolio.h
index 96c7ff57..7f5ba37e 100644
--- a/libsolidity/formal/SMTPortfolio.h
+++ b/libsolidity/formal/SMTPortfolio.h
@@ -22,8 +22,11 @@
#include <libsolidity/interface/ReadFile.h>
+#include <libdevcore/FixedHash.h>
+
#include <boost/noncopyable.hpp>
+#include <map>
#include <vector>
namespace dev
@@ -42,20 +45,19 @@ namespace smt
class SMTPortfolio: public SolverInterface, public boost::noncopyable
{
public:
- SMTPortfolio(ReadCallback::Callback const& _readCallback);
+ SMTPortfolio(std::map<h256, std::string> const& _smtlib2Responses);
void reset() override;
void push() override;
void pop() override;
- void declareFunction(std::string _name, Sort _domain, Sort _codomain) override;
- void declareInteger(std::string _name) override;
- void declareBool(std::string _name) override;
+ void declareVariable(std::string const&, Sort const&) override;
void addAssertion(Expression const& _expr) override;
std::pair<CheckResult, std::vector<std::string>> check(std::vector<Expression> const& _expressionsToEvaluate) override;
+ std::vector<std::string> unhandledQueries() override { return m_solvers.at(0)->unhandledQueries(); }
private:
static bool solverAnswered(CheckResult result);
diff --git a/libsolidity/formal/SolverInterface.h b/libsolidity/formal/SolverInterface.h
index af1cc8e4..cc8214de 100644
--- a/libsolidity/formal/SolverInterface.h
+++ b/libsolidity/formal/SolverInterface.h
@@ -17,7 +17,7 @@
#pragma once
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <libsolidity/interface/ReadFile.h>
#include <libdevcore/Common.h>
@@ -42,12 +42,58 @@ enum class CheckResult
SATISFIABLE, UNSATISFIABLE, UNKNOWN, CONFLICTING, ERROR
};
-enum class Sort
+enum class Kind
{
Int,
Bool,
- IntIntFun, // Function of one Int returning a single Int
- IntBoolFun // Function of one Int returning a single Bool
+ Function,
+ Array
+};
+
+struct Sort
+{
+ Sort(Kind _kind):
+ kind(_kind) {}
+ virtual ~Sort() = default;
+ bool operator==(Sort const& _other) const { return kind == _other.kind; }
+
+ Kind const kind;
+};
+using SortPointer = std::shared_ptr<Sort>;
+
+struct FunctionSort: public Sort
+{
+ FunctionSort(std::vector<SortPointer> _domain, SortPointer _codomain):
+ Sort(Kind::Function), domain(std::move(_domain)), codomain(std::move(_codomain)) {}
+ bool operator==(FunctionSort const& _other) const
+ {
+ if (!std::equal(
+ domain.begin(),
+ domain.end(),
+ _other.domain.begin(),
+ [&](SortPointer _a, SortPointer _b) { return *_a == *_b; }
+ ))
+ return false;
+ return Sort::operator==(_other) && *codomain == *_other.codomain;
+ }
+
+ std::vector<SortPointer> domain;
+ SortPointer codomain;
+};
+
+struct ArraySort: public Sort
+{
+ /// _domain is the sort of the indices
+ /// _range is the sort of the values
+ ArraySort(SortPointer _domain, SortPointer _range):
+ Sort(Kind::Array), domain(std::move(_domain)), range(std::move(_range)) {}
+ bool operator==(ArraySort const& _other) const
+ {
+ return Sort::operator==(_other) && *domain == *_other.domain && *range == *_other.range;
+ }
+
+ SortPointer domain;
+ SortPointer range;
};
/// C++ representation of an SMTLIB2 expression.
@@ -55,10 +101,10 @@ class Expression
{
friend class SolverInterface;
public:
- explicit Expression(bool _v): name(_v ? "true" : "false"), sort(Sort::Bool) {}
- Expression(size_t _number): name(std::to_string(_number)), sort(Sort::Int) {}
- Expression(u256 const& _number): name(_number.str()), sort(Sort::Int) {}
- Expression(bigint const& _number): name(_number.str()), sort(Sort::Int) {}
+ explicit Expression(bool _v): Expression(_v ? "true" : "false", Kind::Bool) {}
+ Expression(size_t _number): Expression(std::to_string(_number), Kind::Int) {}
+ Expression(u256 const& _number): Expression(_number.str(), Kind::Int) {}
+ Expression(bigint const& _number): Expression(_number.str(), Kind::Int) {}
Expression(Expression const&) = default;
Expression(Expression&&) = default;
@@ -80,14 +126,16 @@ public:
{"+", 2},
{"-", 2},
{"*", 2},
- {"/", 2}
+ {"/", 2},
+ {"select", 2},
+ {"store", 3}
};
return operatorsArity.count(name) && operatorsArity.at(name) == arguments.size();
}
static Expression ite(Expression _condition, Expression _trueValue, Expression _falseValue)
{
- solAssert(_trueValue.sort == _falseValue.sort, "");
+ solAssert(*_trueValue.sort == *_falseValue.sort, "");
return Expression("ite", std::vector<Expression>{
std::move(_condition), std::move(_trueValue), std::move(_falseValue)
}, _trueValue.sort);
@@ -98,21 +146,51 @@ public:
return !std::move(_a) || std::move(_b);
}
+ /// select is the SMT representation of an array index access.
+ static Expression select(Expression _array, Expression _index)
+ {
+ solAssert(_array.sort->kind == Kind::Array, "");
+ auto const& arraySort = dynamic_cast<ArraySort const*>(_array.sort.get());
+ solAssert(arraySort, "");
+ solAssert(*arraySort->domain == *_index.sort, "");
+ return Expression(
+ "select",
+ std::vector<Expression>{std::move(_array), std::move(_index)},
+ arraySort->range
+ );
+ }
+
+ /// store is the SMT representation of an assignment to array index.
+ /// The function is pure and returns the modified array.
+ static Expression store(Expression _array, Expression _index, Expression _element)
+ {
+ solAssert(_array.sort->kind == Kind::Array, "");
+ auto const& arraySort = dynamic_cast<ArraySort const*>(_array.sort.get());
+ solAssert(arraySort, "");
+ solAssert(*arraySort->domain == *_index.sort, "");
+ solAssert(*arraySort->range == *_element.sort, "");
+ return Expression(
+ "store",
+ std::vector<Expression>{std::move(_array), std::move(_index), std::move(_element)},
+ _array.sort
+ );
+ }
+
friend Expression operator!(Expression _a)
{
- return Expression("not", std::move(_a), Sort::Bool);
+ return Expression("not", std::move(_a), Kind::Bool);
}
friend Expression operator&&(Expression _a, Expression _b)
{
- return Expression("and", std::move(_a), std::move(_b), Sort::Bool);
+ return Expression("and", std::move(_a), std::move(_b), Kind::Bool);
}
friend Expression operator||(Expression _a, Expression _b)
{
- return Expression("or", std::move(_a), std::move(_b), Sort::Bool);
+ return Expression("or", std::move(_a), std::move(_b), Kind::Bool);
}
friend Expression operator==(Expression _a, Expression _b)
{
- return Expression("=", std::move(_a), std::move(_b), Sort::Bool);
+ return Expression("=", std::move(_a), std::move(_b), Kind::Bool);
}
friend Expression operator!=(Expression _a, Expression _b)
{
@@ -120,72 +198,64 @@ public:
}
friend Expression operator<(Expression _a, Expression _b)
{
- return Expression("<", std::move(_a), std::move(_b), Sort::Bool);
+ return Expression("<", std::move(_a), std::move(_b), Kind::Bool);
}
friend Expression operator<=(Expression _a, Expression _b)
{
- return Expression("<=", std::move(_a), std::move(_b), Sort::Bool);
+ return Expression("<=", std::move(_a), std::move(_b), Kind::Bool);
}
friend Expression operator>(Expression _a, Expression _b)
{
- return Expression(">", std::move(_a), std::move(_b), Sort::Bool);
+ return Expression(">", std::move(_a), std::move(_b), Kind::Bool);
}
friend Expression operator>=(Expression _a, Expression _b)
{
- return Expression(">=", std::move(_a), std::move(_b), Sort::Bool);
+ return Expression(">=", std::move(_a), std::move(_b), Kind::Bool);
}
friend Expression operator+(Expression _a, Expression _b)
{
- return Expression("+", std::move(_a), std::move(_b), Sort::Int);
+ return Expression("+", std::move(_a), std::move(_b), Kind::Int);
}
friend Expression operator-(Expression _a, Expression _b)
{
- return Expression("-", std::move(_a), std::move(_b), Sort::Int);
+ return Expression("-", std::move(_a), std::move(_b), Kind::Int);
}
friend Expression operator*(Expression _a, Expression _b)
{
- return Expression("*", std::move(_a), std::move(_b), Sort::Int);
+ return Expression("*", std::move(_a), std::move(_b), Kind::Int);
}
friend Expression operator/(Expression _a, Expression _b)
{
- return Expression("/", std::move(_a), std::move(_b), Sort::Int);
+ return Expression("/", std::move(_a), std::move(_b), Kind::Int);
}
- Expression operator()(Expression _a) const
+ Expression operator()(std::vector<Expression> _arguments) const
{
solAssert(
- arguments.empty(),
+ sort->kind == Kind::Function,
"Attempted function application to non-function."
);
- switch (sort)
- {
- case Sort::IntIntFun:
- return Expression(name, _a, Sort::Int);
- case Sort::IntBoolFun:
- return Expression(name, _a, Sort::Bool);
- default:
- solAssert(
- false,
- "Attempted function application to invalid type."
- );
- break;
- }
+ auto fSort = dynamic_cast<FunctionSort const*>(sort.get());
+ solAssert(fSort, "");
+ return Expression(name, std::move(_arguments), fSort->codomain);
}
std::string name;
std::vector<Expression> arguments;
- Sort sort;
+ SortPointer sort;
private:
- /// Manual constructor, should only be used by SolverInterface and this class itself.
- Expression(std::string _name, std::vector<Expression> _arguments, Sort _sort):
- name(std::move(_name)), arguments(std::move(_arguments)), sort(_sort) {}
-
- explicit Expression(std::string _name, Sort _sort):
- Expression(std::move(_name), std::vector<Expression>{}, _sort) {}
- Expression(std::string _name, Expression _arg, Sort _sort):
- Expression(std::move(_name), std::vector<Expression>{std::move(_arg)}, _sort) {}
- Expression(std::string _name, Expression _arg1, Expression _arg2, Sort _sort):
- Expression(std::move(_name), std::vector<Expression>{std::move(_arg1), std::move(_arg2)}, _sort) {}
+ /// Manual constructors, should only be used by SolverInterface and this class itself.
+ Expression(std::string _name, std::vector<Expression> _arguments, SortPointer _sort):
+ name(std::move(_name)), arguments(std::move(_arguments)), sort(std::move(_sort)) {}
+ Expression(std::string _name, std::vector<Expression> _arguments, Kind _kind):
+ Expression(std::move(_name), std::move(_arguments), std::make_shared<Sort>(_kind)) {}
+
+ explicit Expression(std::string _name, Kind _kind):
+ Expression(std::move(_name), std::vector<Expression>{}, _kind) {}
+ Expression(std::string _name, Expression _arg, Kind _kind):
+ Expression(std::move(_name), std::vector<Expression>{std::move(_arg)}, _kind) {}
+ Expression(std::string _name, Expression _arg1, Expression _arg2, Kind _kind):
+ Expression(std::move(_name), std::vector<Expression>{std::move(_arg1), std::move(_arg2)}, _kind) {}
};
DEV_SIMPLE_EXCEPTION(SolverError);
@@ -199,36 +269,12 @@ public:
virtual void push() = 0;
virtual void pop() = 0;
- virtual void declareFunction(std::string _name, Sort _domain, Sort _codomain) = 0;
- Expression newFunction(std::string _name, Sort _domain, Sort _codomain)
- {
- declareFunction(_name, _domain, _codomain);
- solAssert(_domain == Sort::Int, "Function sort not supported.");
- // Subclasses should do something here
- switch (_codomain)
- {
- case Sort::Int:
- return Expression(std::move(_name), {}, Sort::IntIntFun);
- case Sort::Bool:
- return Expression(std::move(_name), {}, Sort::IntBoolFun);
- default:
- solAssert(false, "Function sort not supported.");
- break;
- }
- }
- virtual void declareInteger(std::string _name) = 0;
- Expression newInteger(std::string _name)
+ virtual void declareVariable(std::string const& _name, Sort const& _sort) = 0;
+ Expression newVariable(std::string _name, SortPointer _sort)
{
// Subclasses should do something here
- declareInteger(_name);
- return Expression(std::move(_name), {}, Sort::Int);
- }
- virtual void declareBool(std::string _name) = 0;
- Expression newBool(std::string _name)
- {
- // Subclasses should do something here
- declareBool(_name);
- return Expression(std::move(_name), {}, Sort::Bool);
+ declareVariable(_name, *_sort);
+ return Expression(std::move(_name), {}, std::move(_sort));
}
virtual void addAssertion(Expression const& _expr) = 0;
@@ -238,6 +284,9 @@ public:
virtual std::pair<CheckResult, std::vector<std::string>>
check(std::vector<Expression> const& _expressionsToEvaluate) = 0;
+ /// @returns a list of queries that the system was not able to respond to.
+ virtual std::vector<std::string> unhandledQueries() { return {}; }
+
protected:
// SMT query timeout in milliseconds.
static int const queryTimeout = 10000;
diff --git a/libsolidity/formal/SymbolicTypes.cpp b/libsolidity/formal/SymbolicTypes.cpp
index 3eb1c1ce..c297c807 100644
--- a/libsolidity/formal/SymbolicTypes.cpp
+++ b/libsolidity/formal/SymbolicTypes.cpp
@@ -24,6 +24,50 @@
using namespace std;
using namespace dev::solidity;
+smt::SortPointer dev::solidity::smtSort(Type const& _type)
+{
+ switch (smtKind(_type.category()))
+ {
+ case smt::Kind::Int:
+ return make_shared<smt::Sort>(smt::Kind::Int);
+ case smt::Kind::Bool:
+ return make_shared<smt::Sort>(smt::Kind::Bool);
+ case smt::Kind::Function:
+ {
+ auto fType = dynamic_cast<FunctionType const*>(&_type);
+ solAssert(fType, "");
+ vector<smt::SortPointer> parameterSorts = smtSort(fType->parameterTypes());
+ auto returnTypes = fType->returnParameterTypes();
+ // TODO remove this when we support tuples.
+ solAssert(returnTypes.size() == 1, "");
+ smt::SortPointer returnSort = smtSort(*returnTypes.at(0));
+ return make_shared<smt::FunctionSort>(parameterSorts, returnSort);
+ }
+ case smt::Kind::Array:
+ {
+ solUnimplementedAssert(false, "Invalid type");
+ }
+ }
+ solAssert(false, "Invalid type");
+}
+
+vector<smt::SortPointer> dev::solidity::smtSort(vector<TypePointer> const& _types)
+{
+ vector<smt::SortPointer> sorts;
+ for (auto const& type: _types)
+ sorts.push_back(smtSort(*type));
+ return sorts;
+}
+
+smt::Kind dev::solidity::smtKind(Type::Category _category)
+{
+ if (isNumber(_category))
+ return smt::Kind::Int;
+ else if (isBool(_category))
+ return smt::Kind::Bool;
+ solAssert(false, "Invalid type");
+}
+
bool dev::solidity::isSupportedType(Type::Category _category)
{
return isNumber(_category) ||
@@ -125,3 +169,32 @@ smt::Expression dev::solidity::maxValue(IntegerType const& _type)
{
return smt::Expression(_type.maxValue());
}
+
+void dev::solidity::smt::setSymbolicZeroValue(SymbolicVariable const& _variable, smt::SolverInterface& _interface)
+{
+ setSymbolicZeroValue(_variable.currentValue(), _variable.type(), _interface);
+}
+
+void dev::solidity::smt::setSymbolicZeroValue(smt::Expression _expr, TypePointer const& _type, smt::SolverInterface& _interface)
+{
+ if (isInteger(_type->category()))
+ _interface.addAssertion(_expr == 0);
+ else if (isBool(_type->category()))
+ _interface.addAssertion(_expr == smt::Expression(false));
+}
+
+void dev::solidity::smt::setSymbolicUnknownValue(SymbolicVariable const& _variable, smt::SolverInterface& _interface)
+{
+ setSymbolicUnknownValue(_variable.currentValue(), _variable.type(), _interface);
+}
+
+void dev::solidity::smt::setSymbolicUnknownValue(smt::Expression _expr, TypePointer const& _type, smt::SolverInterface& _interface)
+{
+ if (isInteger(_type->category()))
+ {
+ auto intType = dynamic_cast<IntegerType const*>(_type.get());
+ solAssert(intType, "");
+ _interface.addAssertion(_expr >= minValue(*intType));
+ _interface.addAssertion(_expr <= maxValue(*intType));
+ }
+}
diff --git a/libsolidity/formal/SymbolicTypes.h b/libsolidity/formal/SymbolicTypes.h
index dcdd9ea4..984653b3 100644
--- a/libsolidity/formal/SymbolicTypes.h
+++ b/libsolidity/formal/SymbolicTypes.h
@@ -28,6 +28,12 @@ namespace dev
namespace solidity
{
+/// Returns the SMT sort that models the Solidity type _type.
+smt::SortPointer smtSort(Type const& _type);
+std::vector<smt::SortPointer> smtSort(std::vector<TypePointer> const& _types);
+/// Returns the SMT kind that models the Solidity type type category _category.
+smt::Kind smtKind(Type::Category _category);
+
/// So far int, bool and address are supported.
/// Returns true if type is supported.
bool isSupportedType(Type::Category _category);
@@ -49,5 +55,15 @@ std::pair<bool, std::shared_ptr<SymbolicVariable>> newSymbolicVariable(Type cons
smt::Expression minValue(IntegerType const& _type);
smt::Expression maxValue(IntegerType const& _type);
+namespace smt
+{
+
+void setSymbolicZeroValue(SymbolicVariable const& _variable, smt::SolverInterface& _interface);
+void setSymbolicZeroValue(smt::Expression _expr, TypePointer const& _type, smt::SolverInterface& _interface);
+void setSymbolicUnknownValue(SymbolicVariable const& _variable, smt::SolverInterface& _interface);
+void setSymbolicUnknownValue(smt::Expression _expr, TypePointer const& _type, smt::SolverInterface& _interface);
+
+}
+
}
}
diff --git a/libsolidity/formal/SymbolicVariables.cpp b/libsolidity/formal/SymbolicVariables.cpp
index 85818ba0..efaeb97a 100644
--- a/libsolidity/formal/SymbolicVariables.cpp
+++ b/libsolidity/formal/SymbolicVariables.cpp
@@ -37,6 +37,11 @@ SymbolicVariable::SymbolicVariable(
{
}
+string SymbolicVariable::currentName() const
+{
+ return uniqueSymbol(m_ssa->index());
+}
+
string SymbolicVariable::uniqueSymbol(unsigned _index) const
{
return m_uniqueName + "_" + to_string(_index);
@@ -54,16 +59,7 @@ SymbolicBoolVariable::SymbolicBoolVariable(
smt::Expression SymbolicBoolVariable::valueAtIndex(int _index) const
{
- return m_interface.newBool(uniqueSymbol(_index));
-}
-
-void SymbolicBoolVariable::setZeroValue()
-{
- m_interface.addAssertion(currentValue() == smt::Expression(false));
-}
-
-void SymbolicBoolVariable::setUnknownValue()
-{
+ return m_interface.newVariable(uniqueSymbol(_index), make_shared<smt::Sort>(smt::Kind::Bool));
}
SymbolicIntVariable::SymbolicIntVariable(
@@ -78,20 +74,7 @@ SymbolicIntVariable::SymbolicIntVariable(
smt::Expression SymbolicIntVariable::valueAtIndex(int _index) const
{
- return m_interface.newInteger(uniqueSymbol(_index));
-}
-
-void SymbolicIntVariable::setZeroValue()
-{
- m_interface.addAssertion(currentValue() == 0);
-}
-
-void SymbolicIntVariable::setUnknownValue()
-{
- auto intType = dynamic_cast<IntegerType const*>(m_type.get());
- solAssert(intType, "");
- m_interface.addAssertion(currentValue() >= minValue(*intType));
- m_interface.addAssertion(currentValue() <= maxValue(*intType));
+ return m_interface.newVariable(uniqueSymbol(_index), make_shared<smt::Sort>(smt::Kind::Int));
}
SymbolicAddressVariable::SymbolicAddressVariable(
diff --git a/libsolidity/formal/SymbolicVariables.h b/libsolidity/formal/SymbolicVariables.h
index 4fd9b245..fcf32760 100644
--- a/libsolidity/formal/SymbolicVariables.h
+++ b/libsolidity/formal/SymbolicVariables.h
@@ -51,6 +51,8 @@ public:
return valueAtIndex(m_ssa->index());
}
+ std::string currentName() const;
+
virtual smt::Expression valueAtIndex(int _index) const = 0;
smt::Expression increaseIndex()
@@ -62,20 +64,15 @@ public:
unsigned index() const { return m_ssa->index(); }
unsigned& index() { return m_ssa->index(); }
- /// Sets the var to the default value of its type.
- /// Inherited types must implement.
- virtual void setZeroValue() = 0;
- /// The unknown value is the full range of valid values.
- /// It is sub-type dependent, but not mandatory.
- virtual void setUnknownValue() {}
+ TypePointer const& type() const { return m_type; }
protected:
std::string uniqueSymbol(unsigned _index) const;
- TypePointer m_type = nullptr;
+ TypePointer m_type;
std::string m_uniqueName;
smt::SolverInterface& m_interface;
- std::shared_ptr<SSAVariable> m_ssa = nullptr;
+ std::shared_ptr<SSAVariable> m_ssa;
};
/**
@@ -90,11 +87,6 @@ public:
smt::SolverInterface& _interface
);
- /// Sets the var to false.
- void setZeroValue();
- /// Does nothing since the SMT solver already knows the valid values for Bool.
- void setUnknownValue();
-
protected:
smt::Expression valueAtIndex(int _index) const;
};
@@ -111,11 +103,6 @@ public:
smt::SolverInterface& _interface
);
- /// Sets the var to 0.
- void setZeroValue();
- /// Sets the variable to the full valid value range.
- void setUnknownValue();
-
protected:
smt::Expression valueAtIndex(int _index) const;
};
diff --git a/libsolidity/formal/Z3Interface.cpp b/libsolidity/formal/Z3Interface.cpp
index 9a0ccf48..cb01dc61 100644
--- a/libsolidity/formal/Z3Interface.cpp
+++ b/libsolidity/formal/Z3Interface.cpp
@@ -17,7 +17,7 @@
#include <libsolidity/formal/Z3Interface.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <libdevcore/CommonIO.h>
@@ -51,22 +51,22 @@ void Z3Interface::pop()
m_solver.pop();
}
-void Z3Interface::declareFunction(string _name, Sort _domain, Sort _codomain)
+void Z3Interface::declareVariable(string const& _name, Sort const& _sort)
{
- if (!m_functions.count(_name))
- m_functions.insert({_name, m_context.function(_name.c_str(), z3Sort(_domain), z3Sort(_codomain))});
-}
-
-void Z3Interface::declareInteger(string _name)
-{
- if (!m_constants.count(_name))
- m_constants.insert({_name, m_context.int_const(_name.c_str())});
+ if (_sort.kind == Kind::Function)
+ declareFunction(_name, _sort);
+ else if (!m_constants.count(_name))
+ m_constants.insert({_name, m_context.constant(_name.c_str(), z3Sort(_sort))});
}
-void Z3Interface::declareBool(string _name)
+void Z3Interface::declareFunction(string const& _name, Sort const& _sort)
{
- if (!m_constants.count(_name))
- m_constants.insert({_name, m_context.bool_const(_name.c_str())});
+ solAssert(_sort.kind == smt::Kind::Function, "");
+ if (!m_functions.count(_name))
+ {
+ FunctionSort fSort = dynamic_cast<FunctionSort const&>(_sort);
+ m_functions.insert({_name, m_context.function(_name.c_str(), z3Sort(fSort.domain), z3Sort(*fSort.codomain))});
+ }
}
void Z3Interface::addAssertion(Expression const& _expr)
@@ -163,19 +163,28 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
return arguments[0] * arguments[1];
else if (n == "/")
return arguments[0] / arguments[1];
+ else if (n == "select")
+ return z3::select(arguments[0], arguments[1]);
+ else if (n == "store")
+ return z3::store(arguments[0], arguments[1], arguments[2]);
// Cannot reach here.
solAssert(false, "");
return arguments[0];
}
-z3::sort Z3Interface::z3Sort(Sort _sort)
+z3::sort Z3Interface::z3Sort(Sort const& _sort)
{
- switch (_sort)
+ switch (_sort.kind)
{
- case Sort::Bool:
+ case Kind::Bool:
return m_context.bool_sort();
- case Sort::Int:
+ case Kind::Int:
return m_context.int_sort();
+ case Kind::Array:
+ {
+ auto const& arraySort = dynamic_cast<ArraySort const&>(_sort);
+ return m_context.array_sort(z3Sort(*arraySort.domain), z3Sort(*arraySort.range));
+ }
default:
break;
}
@@ -183,3 +192,11 @@ z3::sort Z3Interface::z3Sort(Sort _sort)
// Cannot be reached.
return m_context.int_sort();
}
+
+z3::sort_vector Z3Interface::z3Sort(vector<SortPointer> const& _sorts)
+{
+ z3::sort_vector z3Sorts(m_context);
+ for (auto const& _sort: _sorts)
+ z3Sorts.push_back(z3Sort(*_sort));
+ return z3Sorts;
+}
diff --git a/libsolidity/formal/Z3Interface.h b/libsolidity/formal/Z3Interface.h
index 84880ff3..86e1badd 100644
--- a/libsolidity/formal/Z3Interface.h
+++ b/libsolidity/formal/Z3Interface.h
@@ -40,16 +40,17 @@ public:
void push() override;
void pop() override;
- void declareFunction(std::string _name, Sort _domain, Sort _codomain) override;
- void declareInteger(std::string _name) override;
- void declareBool(std::string _name) override;
+ void declareVariable(std::string const& _name, Sort const& _sort) override;
void addAssertion(Expression const& _expr) override;
std::pair<CheckResult, std::vector<std::string>> check(std::vector<Expression> const& _expressionsToEvaluate) override;
private:
+ void declareFunction(std::string const& _name, Sort const& _sort);
+
z3::expr toZ3Expr(Expression const& _expr);
- z3::sort z3Sort(smt::Sort _sort);
+ z3::sort z3Sort(smt::Sort const& _sort);
+ z3::sort_vector z3Sort(std::vector<smt::SortPointer> const& _sorts);
z3::context m_context;
z3::solver m_solver;
diff --git a/libsolidity/inlineasm/AsmPrinter.h b/libsolidity/inlineasm/AsmPrinter.h
deleted file mode 100644
index 72048975..00000000
--- a/libsolidity/inlineasm/AsmPrinter.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- 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 <http://www.gnu.org/licenses/>.
-*/
-/**
- * @author Christian <c@ethdev.com>
- * @date 2017
- * Converts a parsed assembly into its textual form.
- */
-
-#pragma once
-
-#include <libsolidity/inlineasm/AsmDataForward.h>
-
-#include <libyul/YulString.h>
-
-#include <boost/variant.hpp>
-
-namespace dev
-{
-namespace solidity
-{
-namespace assembly
-{
-
-class AsmPrinter: public boost::static_visitor<std::string>
-{
-public:
- explicit AsmPrinter(bool _yul = false): m_yul(_yul) {}
-
- std::string operator()(assembly::Instruction const& _instruction);
- std::string operator()(assembly::Literal const& _literal);
- std::string operator()(assembly::Identifier const& _identifier);
- std::string operator()(assembly::FunctionalInstruction const& _functionalInstruction);
- std::string operator()(assembly::ExpressionStatement const& _expr);
- std::string operator()(assembly::Label const& _label);
- std::string operator()(assembly::StackAssignment const& _assignment);
- std::string operator()(assembly::Assignment const& _assignment);
- std::string operator()(assembly::VariableDeclaration const& _variableDeclaration);
- std::string operator()(assembly::FunctionDefinition const& _functionDefinition);
- std::string operator()(assembly::FunctionCall const& _functionCall);
- std::string operator()(assembly::If const& _if);
- std::string operator()(assembly::Switch const& _switch);
- std::string operator()(assembly::ForLoop const& _forLoop);
- std::string operator()(assembly::Block const& _block);
-
-private:
- std::string formatTypedName(TypedName _variable) const;
- std::string appendTypeName(yul::YulString _type) const;
-
- bool m_yul = false;
-};
-
-}
-}
-}
diff --git a/libsolidity/interface/AssemblyStack.cpp b/libsolidity/interface/AssemblyStack.cpp
index 26496de7..31959d93 100644
--- a/libsolidity/interface/AssemblyStack.cpp
+++ b/libsolidity/interface/AssemblyStack.cpp
@@ -22,37 +22,37 @@
#include <libsolidity/interface/AssemblyStack.h>
-#include <libsolidity/parsing/Scanner.h>
-#include <libsolidity/inlineasm/AsmPrinter.h>
-#include <libsolidity/inlineasm/AsmParser.h>
-#include <libsolidity/inlineasm/AsmAnalysis.h>
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
-#include <libsolidity/inlineasm/AsmCodeGen.h>
-
-#include <libevmasm/Assembly.h>
-
+#include <liblangutil/Scanner.h>
+#include <libyul/AsmPrinter.h>
+#include <libyul/AsmParser.h>
+#include <libyul/AsmAnalysis.h>
+#include <libyul/AsmAnalysisInfo.h>
+#include <libyul/AsmCodeGen.h>
#include <libyul/backends/evm/EVMCodeTransform.h>
#include <libyul/backends/evm/EVMAssembly.h>
+#include <libevmasm/Assembly.h>
+
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
namespace
{
-assembly::AsmFlavour languageToAsmFlavour(AssemblyStack::Language _language)
+yul::AsmFlavour languageToAsmFlavour(AssemblyStack::Language _language)
{
switch (_language)
{
case AssemblyStack::Language::Assembly:
- return assembly::AsmFlavour::Loose;
+ return yul::AsmFlavour::Loose;
case AssemblyStack::Language::StrictAssembly:
- return assembly::AsmFlavour::Strict;
+ return yul::AsmFlavour::Strict;
case AssemblyStack::Language::Yul:
- return assembly::AsmFlavour::Yul;
+ return yul::AsmFlavour::Yul;
}
solAssert(false, "");
- return assembly::AsmFlavour::Yul;
+ return yul::AsmFlavour::Yul;
}
}
@@ -69,7 +69,7 @@ bool AssemblyStack::parseAndAnalyze(std::string const& _sourceName, std::string
m_errors.clear();
m_analysisSuccessful = false;
m_scanner = make_shared<Scanner>(CharStream(_source), _sourceName);
- m_parserResult = assembly::Parser(m_errorReporter, languageToAsmFlavour(m_language)).parse(m_scanner, false);
+ m_parserResult = yul::Parser(m_errorReporter, languageToAsmFlavour(m_language)).parse(m_scanner, false);
if (!m_errorReporter.errors().empty())
return false;
solAssert(m_parserResult, "");
@@ -77,21 +77,21 @@ bool AssemblyStack::parseAndAnalyze(std::string const& _sourceName, std::string
return analyzeParsed();
}
-bool AssemblyStack::analyze(assembly::Block const& _block, Scanner const* _scanner)
+bool AssemblyStack::analyze(yul::Block const& _block, Scanner const* _scanner)
{
m_errors.clear();
m_analysisSuccessful = false;
if (_scanner)
m_scanner = make_shared<Scanner>(*_scanner);
- m_parserResult = make_shared<assembly::Block>(_block);
+ m_parserResult = make_shared<yul::Block>(_block);
return analyzeParsed();
}
bool AssemblyStack::analyzeParsed()
{
- m_analysisInfo = make_shared<assembly::AsmAnalysisInfo>();
- assembly::AsmAnalyzer analyzer(*m_analysisInfo, m_errorReporter, m_evmVersion, boost::none, languageToAsmFlavour(m_language));
+ m_analysisInfo = make_shared<yul::AsmAnalysisInfo>();
+ yul::AsmAnalyzer analyzer(*m_analysisInfo, m_errorReporter, m_evmVersion, boost::none, languageToAsmFlavour(m_language));
m_analysisSuccessful = analyzer.analyze(*m_parserResult);
return m_analysisSuccessful;
}
@@ -108,7 +108,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
{
MachineAssemblyObject object;
eth::Assembly assembly;
- assembly::CodeGenerator::assemble(*m_parserResult, *m_analysisInfo, assembly);
+ yul::CodeGenerator::assemble(*m_parserResult, *m_analysisInfo, assembly);
object.bytecode = make_shared<eth::LinkerObject>(assembly.assemble());
object.assembly = assembly.assemblyString();
return object;
@@ -132,5 +132,5 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
string AssemblyStack::print() const
{
solAssert(m_parserResult, "");
- return assembly::AsmPrinter(m_language == Language::Yul)(*m_parserResult);
+ return yul::AsmPrinter(m_language == Language::Yul)(*m_parserResult);
}
diff --git a/libsolidity/interface/AssemblyStack.h b/libsolidity/interface/AssemblyStack.h
index 8132ce63..03b811db 100644
--- a/libsolidity/interface/AssemblyStack.h
+++ b/libsolidity/interface/AssemblyStack.h
@@ -21,25 +21,30 @@
#pragma once
-#include <libsolidity/interface/ErrorReporter.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/ErrorReporter.h>
+#include <liblangutil/EVMVersion.h>
#include <libevmasm/LinkerObject.h>
#include <string>
#include <memory>
-namespace dev
-{
-namespace solidity
+namespace langutil
{
class Scanner;
-namespace assembly
+}
+
+namespace yul
{
struct AsmAnalysisInfo;
struct Block;
}
+namespace dev
+{
+namespace solidity
+{
+
struct MachineAssemblyObject
{
std::shared_ptr<eth::LinkerObject> bytecode;
@@ -61,7 +66,7 @@ public:
{}
/// @returns the scanner used during parsing
- Scanner const& scanner() const;
+ langutil::Scanner const& scanner() const;
/// Runs parsing and analysis steps, returns false if input cannot be assembled.
/// Multiple calls overwrite the previous state.
@@ -69,13 +74,13 @@ public:
/// Runs analysis step on the supplied block, returns false if input cannot be assembled.
/// Multiple calls overwrite the previous state.
- bool analyze(assembly::Block const& _block, Scanner const* _scanner = nullptr);
+ bool analyze(yul::Block const& _block, langutil::Scanner const* _scanner = nullptr);
/// Run the assembly step (should only be called after parseAndAnalyze).
MachineAssemblyObject assemble(Machine _machine) const;
/// @returns the errors generated during parsing, analysis (and potentially assembly).
- ErrorList const& errors() const { return m_errors; }
+ langutil::ErrorList const& errors() const { return m_errors; }
/// Pretty-print the input after having parsed it.
std::string print() const;
@@ -86,13 +91,13 @@ private:
Language m_language = Language::Assembly;
EVMVersion m_evmVersion;
- std::shared_ptr<Scanner> m_scanner;
+ std::shared_ptr<langutil::Scanner> m_scanner;
bool m_analysisSuccessful = false;
- std::shared_ptr<assembly::Block> m_parserResult;
- std::shared_ptr<assembly::AsmAnalysisInfo> m_analysisInfo;
- ErrorList m_errors;
- ErrorReporter m_errorReporter;
+ std::shared_ptr<yul::Block> m_parserResult;
+ std::shared_ptr<yul::AsmAnalysisInfo> m_analysisInfo;
+ langutil::ErrorList m_errors;
+ langutil::ErrorReporter m_errorReporter;
};
}
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp
index d6a63f1d..de4a7ec2 100644
--- a/libsolidity/interface/CompilerStack.cpp
+++ b/libsolidity/interface/CompilerStack.cpp
@@ -27,7 +27,6 @@
#include <libsolidity/interface/Version.h>
#include <libsolidity/analysis/SemVerHandler.h>
#include <libsolidity/ast/AST.h>
-#include <libsolidity/parsing/Scanner.h>
#include <libsolidity/parsing/Parser.h>
#include <libsolidity/analysis/ControlFlowAnalyzer.h>
#include <libsolidity/analysis/ControlFlowGraph.h>
@@ -45,10 +44,12 @@
#include <libsolidity/interface/Natspec.h>
#include <libsolidity/interface/GasEstimator.h>
-#include <libevmasm/Exceptions.h>
-
#include <libyul/YulString.h>
+#include <liblangutil/Scanner.h>
+
+#include <libevmasm/Exceptions.h>
+
#include <libdevcore/SwarmHash.h>
#include <libdevcore/JSON.h>
@@ -58,6 +59,7 @@
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
boost::optional<CompilerStack::Remapping> CompilerStack::parseRemapping(string const& _remapping)
@@ -106,6 +108,8 @@ void CompilerStack::reset(bool _keepSources)
m_stackState = Empty;
m_sources.clear();
}
+ m_smtlib2Responses.clear();
+ m_unhandledSMTLib2Queries.clear();
m_libraries.clear();
m_evmVersion = EVMVersion();
m_optimize = false;
@@ -282,9 +286,10 @@ bool CompilerStack::analyze()
if (noErrors)
{
- SMTChecker smtChecker(m_errorReporter, m_smtQuery);
+ SMTChecker smtChecker(m_errorReporter, m_smtlib2Responses);
for (Source const* source: m_sourceOrder)
smtChecker.analyze(*source->ast, source->scanner);
+ m_unhandledSMTLib2Queries += smtChecker.unhandledQueries();
}
}
catch(FatalError const&)
diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h
index 9a15fbf0..2c7add3b 100644
--- a/libsolidity/interface/CompilerStack.h
+++ b/libsolidity/interface/CompilerStack.h
@@ -23,11 +23,12 @@
#pragma once
-#include <libsolidity/interface/ErrorReporter.h>
#include <libsolidity/interface/ReadFile.h>
-#include <libsolidity/interface/EVMVersion.h>
-#include <libevmasm/SourceLocation.h>
+#include <liblangutil/ErrorReporter.h>
+#include <liblangutil/EVMVersion.h>
+#include <liblangutil/SourceLocation.h>
+
#include <libevmasm/LinkerObject.h>
#include <libdevcore/Common.h>
@@ -43,6 +44,11 @@
#include <vector>
#include <functional>
+namespace langutil
+{
+class Scanner;
+}
+
namespace dev
{
@@ -57,7 +63,6 @@ namespace solidity
{
// forward declarations
-class Scanner;
class ASTNode;
class ContractDefinition;
class FunctionDefinition;
@@ -65,7 +70,6 @@ class SourceUnit;
class Compiler;
class GlobalContext;
class Natspec;
-class Error;
class DeclarationContainer;
/**
@@ -100,7 +104,7 @@ public:
m_errorReporter(m_errorList) {}
/// @returns the list of errors that occurred during parsing and type checking.
- ErrorList const& errors() const { return m_errorReporter.errors(); }
+ langutil::ErrorList const& errors() const { return m_errorReporter.errors(); }
/// @returns the current state.
State state() const { return m_stackState; }
@@ -149,6 +153,9 @@ public:
/// @returns true if a source object by the name already existed and was replaced.
bool addSource(std::string const& _name, std::string const& _content, bool _isLibrary = false);
+ /// Adds a response to an SMTLib2 query (identified by the hash of the query input).
+ void addSMTLib2Response(h256 const& _hash, std::string const& _response) { m_smtlib2Responses[_hash] = _response; }
+
/// Parses all source units that were added
/// @returns false on error.
bool parse();
@@ -174,7 +181,7 @@ public:
std::map<std::string, unsigned> sourceIndices() const;
/// @returns the previously used scanner, useful for counting lines during error reporting.
- Scanner const& scanner(std::string const& _sourceName) const;
+ langutil::Scanner const& scanner(std::string const& _sourceName) const;
/// @returns the parsed source unit with the supplied name.
SourceUnit const& ast(std::string const& _sourceName) const;
@@ -182,7 +189,11 @@ public:
/// Helper function for logs printing. Do only use in error cases, it's quite expensive.
/// line and columns are numbered starting from 1 with following order:
/// start line, start column, end line, end column
- std::tuple<int, int, int, int> positionFromSourceLocation(SourceLocation const& _sourceLocation) const;
+ std::tuple<int, int, int, int> positionFromSourceLocation(langutil::SourceLocation const& _sourceLocation) const;
+
+ /// @returns a list of unhandled queries to the SMT solver (has to be supplied in a second run
+ /// by calling @a addSMTLib2Response).
+ std::vector<std::string> const& unhandledSMTLib2Queries() const { return m_unhandledSMTLib2Queries; }
/// @returns a list of the contract names in the sources.
std::vector<std::string> contractNames() const;
@@ -248,7 +259,7 @@ private:
/// The state per source unit. Filled gradually during parsing.
struct Source
{
- std::shared_ptr<Scanner> scanner;
+ std::shared_ptr<langutil::Scanner> scanner;
std::shared_ptr<SourceUnit> ast;
bool isLibrary = false;
void reset() { scanner.reset(); ast.reset(); }
@@ -330,7 +341,6 @@ private:
) const;
ReadCallback::Callback m_readFile;
- ReadCallback::Callback m_smtQuery;
bool m_optimize = false;
unsigned m_optimizeRuns = 200;
EVMVersion m_evmVersion;
@@ -340,13 +350,15 @@ private:
/// "context:prefix=target"
std::vector<Remapping> m_remappings;
std::map<std::string const, Source> m_sources;
+ std::vector<std::string> m_unhandledSMTLib2Queries;
+ std::map<h256, std::string> m_smtlib2Responses;
std::shared_ptr<GlobalContext> m_globalContext;
std::vector<Source const*> m_sourceOrder;
/// This is updated during compilation.
std::map<ASTNode const*, std::shared_ptr<DeclarationContainer>> m_scopes;
std::map<std::string const, Contract> m_contracts;
- ErrorList m_errorList;
- ErrorReporter m_errorReporter;
+ langutil::ErrorList m_errorList;
+ langutil::ErrorReporter m_errorReporter;
bool m_metadataLiteralSources = false;
State m_stackState = Empty;
};
diff --git a/libsolidity/interface/GasEstimator.cpp b/libsolidity/interface/GasEstimator.cpp
index 1f20366e..de6b2ce5 100644
--- a/libsolidity/interface/GasEstimator.cpp
+++ b/libsolidity/interface/GasEstimator.cpp
@@ -35,6 +35,7 @@
using namespace std;
using namespace dev;
using namespace dev::eth;
+using namespace langutil;
using namespace dev::solidity;
GasEstimator::ASTGasConsumptionSelfAccumulated GasEstimator::structuralEstimation(
diff --git a/libsolidity/interface/GasEstimator.h b/libsolidity/interface/GasEstimator.h
index ea94d988..214a3e58 100644
--- a/libsolidity/interface/GasEstimator.h
+++ b/libsolidity/interface/GasEstimator.h
@@ -22,7 +22,7 @@
#pragma once
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <libevmasm/GasMeter.h>
#include <libevmasm/Assembly.h>
diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp
index c8b03a94..4a32d9f3 100644
--- a/libsolidity/interface/StandardCompiler.cpp
+++ b/libsolidity/interface/StandardCompiler.cpp
@@ -21,7 +21,7 @@
*/
#include <libsolidity/interface/StandardCompiler.h>
-#include <libsolidity/interface/SourceReferenceFormatter.h>
+#include <liblangutil/SourceReferenceFormatter.h>
#include <libsolidity/ast/ASTJsonConverter.h>
#include <libevmasm/Instruction.h>
#include <libdevcore/JSON.h>
@@ -31,6 +31,7 @@
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
namespace {
@@ -318,6 +319,27 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
return formatFatalError("JSONError", "Invalid input source specified.");
}
+ Json::Value const& auxInputs = _input["auxiliaryInput"];
+ if (!!auxInputs)
+ {
+ Json::Value const& smtlib2Responses = auxInputs["smtlib2responses"];
+ if (!!smtlib2Responses)
+ for (auto const& hashString: smtlib2Responses.getMemberNames())
+ {
+ h256 hash;
+ try
+ {
+ hash = h256(hashString);
+ }
+ catch (dev::BadHexCharacter const&)
+ {
+ return formatFatalError("JSONError", "Invalid hex encoding of SMTLib2 auxiliary input.");
+ }
+
+ m_compilerStack.addSMTLib2Response(hash, smtlib2Responses[hashString].asString());
+ }
+ }
+
Json::Value const& settings = _input.get("settings", Json::Value());
if (settings.isMember("evmVersion"))
@@ -411,7 +433,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
Json::Value outputSelection = settings.get("outputSelection", Json::Value());
m_compilerStack.setRequestedContractNames(requestedContractNames(outputSelection));
- auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compilerStack.scanner(_sourceName); };
+ auto scannerFromSourceName = [&](string const& _sourceName) -> Scanner const& { return m_compilerStack.scanner(_sourceName); };
try
{
@@ -517,6 +539,10 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
if (errors.size() > 0)
output["errors"] = errors;
+ if (!m_compilerStack.unhandledSMTLib2Queries().empty())
+ for (string const& query: m_compilerStack.unhandledSMTLib2Queries())
+ output["auxiliaryInputRequested"]["smtlib2queries"]["0x" + keccak256(query).hex()] = query;
+
output["sources"] = Json::objectValue;
unsigned sourceIndex = 0;
for (string const& sourceName: analysisSuccess ? m_compilerStack.sourceNames() : vector<string>())
diff --git a/libsolidity/interface/Version.cpp b/libsolidity/interface/Version.cpp
index b5f68ce8..b785d557 100644
--- a/libsolidity/interface/Version.cpp
+++ b/libsolidity/interface/Version.cpp
@@ -24,7 +24,7 @@
#include <string>
#include <libdevcore/CommonData.h>
#include <libdevcore/Common.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <solidity/BuildInfo.h>
using namespace dev;
diff --git a/libsolidity/parsing/DocStringParser.cpp b/libsolidity/parsing/DocStringParser.cpp
index d9588e5c..d8927fea 100644
--- a/libsolidity/parsing/DocStringParser.cpp
+++ b/libsolidity/parsing/DocStringParser.cpp
@@ -1,13 +1,14 @@
#include <libsolidity/parsing/DocStringParser.h>
-#include <libsolidity/interface/ErrorReporter.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/ErrorReporter.h>
+#include <liblangutil/Exceptions.h>
#include <boost/range/irange.hpp>
#include <boost/range/algorithm.hpp>
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
diff --git a/libsolidity/parsing/DocStringParser.h b/libsolidity/parsing/DocStringParser.h
index 5f2819cc..c83b416d 100644
--- a/libsolidity/parsing/DocStringParser.h
+++ b/libsolidity/parsing/DocStringParser.h
@@ -25,19 +25,22 @@
#include <string>
#include <libsolidity/ast/ASTAnnotations.h>
+namespace langutil
+{
+class ErrorReporter;
+}
+
namespace dev
{
namespace solidity
{
-class ErrorReporter;
-
class DocStringParser
{
public:
/// Parse the given @a _docString and stores the parsed components internally.
/// @returns false on error and appends the error to @a _errors.
- bool parse(std::string const& _docString, ErrorReporter& _errorReporter);
+ bool parse(std::string const& _docString, langutil::ErrorReporter& _errorReporter);
std::multimap<std::string, DocTag> const& tags() const { return m_docTags; }
@@ -63,7 +66,7 @@ private:
/// Mapping tag name -> content.
std::multimap<std::string, DocTag> m_docTags;
DocTag* m_lastTag = nullptr;
- ErrorReporter* m_errorReporter = nullptr;
+ langutil::ErrorReporter* m_errorReporter = nullptr;
bool m_errorsOccurred = false;
};
diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp
index b17dad9a..3f4a015b 100644
--- a/libsolidity/parsing/Parser.cpp
+++ b/libsolidity/parsing/Parser.cpp
@@ -22,13 +22,14 @@
#include <cctype>
#include <vector>
-#include <libevmasm/SourceLocation.h>
#include <libsolidity/parsing/Parser.h>
-#include <libsolidity/parsing/Scanner.h>
-#include <libsolidity/inlineasm/AsmParser.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <libyul/AsmParser.h>
+#include <liblangutil/SourceLocation.h>
+#include <liblangutil/ErrorReporter.h>
+#include <liblangutil/Scanner.h>
using namespace std;
+using namespace langutil;
namespace dev
{
@@ -1011,8 +1012,8 @@ ASTPointer<InlineAssembly> Parser::parseInlineAssembly(ASTPointer<ASTString> con
m_scanner->next();
}
- assembly::Parser asmParser(m_errorReporter);
- shared_ptr<assembly::Block> block = asmParser.parse(m_scanner, true);
+ yul::Parser asmParser(m_errorReporter);
+ shared_ptr<yul::Block> block = asmParser.parse(m_scanner, true);
nodeFactory.markEndPosition();
return nodeFactory.createNode<InlineAssembly>(_docString, block);
}
@@ -1554,8 +1555,8 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
expression = nodeFactory.createNode<TupleExpression>(components, isArray);
break;
}
- case Token::IllegalHex:
- fatalParserError("Expected even number of hex-nibbles within double-quotes.");
+ case Token::Illegal:
+ fatalParserError(to_string(m_scanner->currentError()));
break;
default:
if (TokenTraits::isElementaryTypeName(token))
diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h
index fa974171..15852096 100644
--- a/libsolidity/parsing/Parser.h
+++ b/libsolidity/parsing/Parser.h
@@ -23,21 +23,24 @@
#pragma once
#include <libsolidity/ast/AST.h>
-#include <libsolidity/parsing/ParserBase.h>
+#include <liblangutil/ParserBase.h>
+
+namespace langutil
+{
+class Scanner;
+}
namespace dev
{
namespace solidity
{
-class Scanner;
-
-class Parser: public ParserBase
+class Parser: public langutil::ParserBase
{
public:
- explicit Parser(ErrorReporter& _errorReporter): ParserBase(_errorReporter) {}
+ explicit Parser(langutil::ErrorReporter& _errorReporter): ParserBase(_errorReporter) {}
- ASTPointer<SourceUnit> parse(std::shared_ptr<Scanner> const& _scanner);
+ ASTPointer<SourceUnit> parse(std::shared_ptr<langutil::Scanner> const& _scanner);
private:
class ASTNodeFactory;
@@ -146,7 +149,7 @@ private:
struct IndexAccessedPath
{
std::vector<ASTPointer<PrimaryExpression>> path;
- std::vector<std::pair<ASTPointer<Expression>, SourceLocation>> indices;
+ std::vector<std::pair<ASTPointer<Expression>, langutil::SourceLocation>> indices;
bool empty() const;
};
diff --git a/libsolidity/parsing/Token.h b/libsolidity/parsing/Token.h
index 81e8dd98..d61aefb6 100644
--- a/libsolidity/parsing/Token.h
+++ b/libsolidity/parsing/Token.h
@@ -1,378 +1,36 @@
-// Copyright 2006-2012, the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Modifications as part of solidity under the following license:
-//
-// 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 <http://www.gnu.org/licenses/>.
-
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+/**
+ * Solidity and Yul both share the same Token (and Scanner) API.
+ *
+ * This may (or may not) change in the future. But for the time being, we've put both
+ * at a shared place, and *just* import them.
+*/
#pragma once
-#include <libdevcore/Common.h>
-#include <libsolidity/interface/Exceptions.h>
-#include <libsolidity/parsing/UndefMacros.h>
-#include <iosfwd>
+#include <liblangutil/Token.h>
namespace dev
{
namespace solidity
{
+namespace TokenTraits = ::langutil::TokenTraits;
-// TOKEN_LIST takes a list of 3 macros M, all of which satisfy the
-// same signature M(name, string, precedence), where name is the
-// symbolic token name, string is the corresponding syntactic symbol
-// (or NULL, for literals), and precedence is the precedence (or 0).
-// The parameters are invoked for token categories as follows:
-//
-// T: Non-keyword tokens
-// K: Keyword tokens
-
-// IGNORE_TOKEN is a convenience macro that can be supplied as
-// an argument (at any position) for a TOKEN_LIST call. It does
-// nothing with tokens belonging to the respective category.
-
-#define IGNORE_TOKEN(name, string, precedence)
-
-#define TOKEN_LIST(T, K) \
- /* End of source indicator. */ \
- T(EOS, "EOS", 0) \
- \
- /* Punctuators (ECMA-262, section 7.7, page 15). */ \
- T(LParen, "(", 0) \
- T(RParen, ")", 0) \
- T(LBrack, "[", 0) \
- T(RBrack, "]", 0) \
- T(LBrace, "{", 0) \
- T(RBrace, "}", 0) \
- T(Colon, ":", 0) \
- T(Semicolon, ";", 0) \
- T(Period, ".", 0) \
- T(Conditional, "?", 3) \
- T(Arrow, "=>", 0) \
- \
- /* Assignment operators. */ \
- /* IsAssignmentOp() relies on this block of enum values being */ \
- /* contiguous and sorted in the same order!*/ \
- T(Assign, "=", 2) \
- /* The following have to be in exactly the same order as the simple binary operators*/ \
- T(AssignBitOr, "|=", 2) \
- T(AssignBitXor, "^=", 2) \
- T(AssignBitAnd, "&=", 2) \
- T(AssignShl, "<<=", 2) \
- T(AssignSar, ">>=", 2) \
- T(AssignShr, ">>>=", 2) \
- T(AssignAdd, "+=", 2) \
- T(AssignSub, "-=", 2) \
- T(AssignMul, "*=", 2) \
- T(AssignDiv, "/=", 2) \
- T(AssignMod, "%=", 2) \
- \
- /* Binary operators sorted by precedence. */ \
- /* IsBinaryOp() relies on this block of enum values */ \
- /* being contiguous and sorted in the same order! */ \
- T(Comma, ",", 1) \
- T(Or, "||", 4) \
- T(And, "&&", 5) \
- T(BitOr, "|", 8) \
- T(BitXor, "^", 9) \
- T(BitAnd, "&", 10) \
- T(SHL, "<<", 11) \
- T(SAR, ">>", 11) \
- T(SHR, ">>>", 11) \
- T(Add, "+", 12) \
- T(Sub, "-", 12) \
- T(Mul, "*", 13) \
- T(Div, "/", 13) \
- T(Mod, "%", 13) \
- T(Exp, "**", 14) \
- \
- /* Compare operators sorted by precedence. */ \
- /* IsCompareOp() relies on this block of enum values */ \
- /* being contiguous and sorted in the same order! */ \
- T(Equal, "==", 6) \
- T(NotEqual, "!=", 6) \
- T(LessThan, "<", 7) \
- T(GreaterThan, ">", 7) \
- T(LessThanOrEqual, "<=", 7) \
- T(GreaterThanOrEqual, ">=", 7) \
- \
- /* Unary operators. */ \
- /* IsUnaryOp() relies on this block of enum values */ \
- /* being contiguous and sorted in the same order! */ \
- T(Not, "!", 0) \
- T(BitNot, "~", 0) \
- T(Inc, "++", 0) \
- T(Dec, "--", 0) \
- K(Delete, "delete", 0) \
- \
- /* Keywords */ \
- K(Anonymous, "anonymous", 0) \
- K(As, "as", 0) \
- K(Assembly, "assembly", 0) \
- K(Break, "break", 0) \
- K(Constant, "constant", 0) \
- K(Constructor, "constructor", 0) \
- K(Continue, "continue", 0) \
- K(Contract, "contract", 0) \
- K(Do, "do", 0) \
- K(Else, "else", 0) \
- K(Enum, "enum", 0) \
- K(Emit, "emit", 0) \
- K(Event, "event", 0) \
- K(External, "external", 0) \
- K(For, "for", 0) \
- K(Function, "function", 0) \
- K(Hex, "hex", 0) \
- K(If, "if", 0) \
- K(Indexed, "indexed", 0) \
- K(Interface, "interface", 0) \
- K(Internal, "internal", 0) \
- K(Import, "import", 0) \
- K(Is, "is", 0) \
- K(Library, "library", 0) \
- K(Mapping, "mapping", 0) \
- K(Memory, "memory", 0) \
- K(Modifier, "modifier", 0) \
- K(New, "new", 0) \
- K(Payable, "payable", 0) \
- K(Public, "public", 0) \
- K(Pragma, "pragma", 0) \
- K(Private, "private", 0) \
- K(Pure, "pure", 0) \
- K(Return, "return", 0) \
- K(Returns, "returns", 0) \
- K(Storage, "storage", 0) \
- K(CallData, "calldata", 0) \
- K(Struct, "struct", 0) \
- K(Throw, "throw", 0) \
- K(Using, "using", 0) \
- K(Var, "var", 0) \
- K(View, "view", 0) \
- K(While, "while", 0) \
- \
- /* Ether subdenominations */ \
- K(SubWei, "wei", 0) \
- K(SubSzabo, "szabo", 0) \
- K(SubFinney, "finney", 0) \
- K(SubEther, "ether", 0) \
- K(SubSecond, "seconds", 0) \
- K(SubMinute, "minutes", 0) \
- K(SubHour, "hours", 0) \
- K(SubDay, "days", 0) \
- K(SubWeek, "weeks", 0) \
- K(SubYear, "years", 0) \
- /* type keywords*/ \
- K(Int, "int", 0) \
- K(UInt, "uint", 0) \
- K(Bytes, "bytes", 0) \
- K(Byte, "byte", 0) \
- K(String, "string", 0) \
- K(Address, "address", 0) \
- K(Bool, "bool", 0) \
- K(Fixed, "fixed", 0) \
- K(UFixed, "ufixed", 0) \
- T(IntM, "intM", 0) \
- T(UIntM, "uintM", 0) \
- T(BytesM, "bytesM", 0) \
- T(FixedMxN, "fixedMxN", 0) \
- T(UFixedMxN, "ufixedMxN", 0) \
- T(TypesEnd, NULL, 0) /* used as type enum end marker */ \
- \
- /* Literals */ \
- K(TrueLiteral, "true", 0) \
- K(FalseLiteral, "false", 0) \
- T(Number, NULL, 0) \
- T(StringLiteral, NULL, 0) \
- T(CommentLiteral, NULL, 0) \
- \
- /* Identifiers (not keywords or future reserved words). */ \
- T(Identifier, NULL, 0) \
- \
- /* Keywords reserved for future use. */ \
- K(Abstract, "abstract", 0) \
- K(After, "after", 0) \
- K(Alias, "alias", 0) \
- K(Apply, "apply", 0) \
- K(Auto, "auto", 0) \
- K(Case, "case", 0) \
- K(Catch, "catch", 0) \
- K(CopyOf, "copyof", 0) \
- K(Default, "default", 0) \
- K(Define, "define", 0) \
- K(Final, "final", 0) \
- K(Immutable, "immutable", 0) \
- K(Implements, "implements", 0) \
- K(In, "in", 0) \
- K(Inline, "inline", 0) \
- K(Let, "let", 0) \
- K(Macro, "macro", 0) \
- K(Match, "match", 0) \
- K(Mutable, "mutable", 0) \
- K(NullLiteral, "null", 0) \
- K(Of, "of", 0) \
- K(Override, "override", 0) \
- K(Partial, "partial", 0) \
- K(Promise, "promise", 0) \
- K(Reference, "reference", 0) \
- K(Relocatable, "relocatable", 0) \
- K(Sealed, "sealed", 0) \
- K(Sizeof, "sizeof", 0) \
- K(Static, "static", 0) \
- K(Supports, "supports", 0) \
- K(Switch, "switch", 0) \
- K(Try, "try", 0) \
- K(Type, "type", 0) \
- K(Typedef, "typedef", 0) \
- K(TypeOf, "typeof", 0) \
- K(Unchecked, "unchecked", 0) \
- \
- /* Illegal token - not able to scan. */ \
- T(Illegal, "ILLEGAL", 0) \
- /* Illegal hex token */ \
- T(IllegalHex, "ILLEGAL_HEX", 0) \
- \
- /* Scanner-internal use only. */ \
- T(Whitespace, NULL, 0)
-
-// All token values.
-// attention! msvc issue:
-// http://stackoverflow.com/questions/9567868/compile-errors-after-adding-v8-to-my-project-c2143-c2059
-// @todo: avoid TOKEN_LIST macro
-enum class Token : unsigned int {
-#define T(name, string, precedence) name,
- TOKEN_LIST(T, T)
- NUM_TOKENS
-#undef T
-};
-
-namespace TokenTraits
-{
- constexpr size_t count() { return static_cast<size_t>(Token::NUM_TOKENS); }
-
- // Predicates
- constexpr bool isElementaryTypeName(Token tok) { return Token::Int <= tok && tok < Token::TypesEnd; }
- constexpr bool isAssignmentOp(Token tok) { return Token::Assign <= tok && tok <= Token::AssignMod; }
- constexpr bool isBinaryOp(Token op) { return Token::Comma <= op && op <= Token::Exp; }
- constexpr bool isCommutativeOp(Token op) { return op == Token::BitOr || op == Token::BitXor || op == Token::BitAnd ||
- op == Token::Add || op == Token::Mul || op == Token::Equal || op == Token::NotEqual; }
- constexpr bool isArithmeticOp(Token op) { return Token::Add <= op && op <= Token::Exp; }
- constexpr bool isCompareOp(Token op) { return Token::Equal <= op && op <= Token::GreaterThanOrEqual; }
-
- constexpr bool isBitOp(Token op) { return (Token::BitOr <= op && op <= Token::BitAnd) || op == Token::BitNot; }
- constexpr bool isBooleanOp(Token op) { return (Token::Or <= op && op <= Token::And) || op == Token::Not; }
- constexpr bool isUnaryOp(Token op) { return (Token::Not <= op && op <= Token::Delete) || op == Token::Add || op == Token::Sub; }
- constexpr bool isCountOp(Token op) { return op == Token::Inc || op == Token::Dec; }
- constexpr bool isShiftOp(Token op) { return (Token::SHL <= op) && (op <= Token::SHR); }
- constexpr bool isVariableVisibilitySpecifier(Token op) { return op == Token::Public || op == Token::Private || op == Token::Internal; }
- constexpr bool isVisibilitySpecifier(Token op) { return isVariableVisibilitySpecifier(op) || op == Token::External; }
- constexpr bool isLocationSpecifier(Token op) { return op == Token::Memory || op == Token::Storage || op == Token::CallData; }
-
- constexpr bool isStateMutabilitySpecifier(Token op, bool _allowConstant = true)
- {
- return (op == Token::Constant && _allowConstant)
- || op == Token::Pure || op == Token::View || op == Token::Payable;
- }
-
- constexpr bool isEtherSubdenomination(Token op) { return op == Token::SubWei || op == Token::SubSzabo || op == Token::SubFinney || op == Token::SubEther; }
- constexpr bool isTimeSubdenomination(Token op) { return op == Token::SubSecond || op == Token::SubMinute || op == Token::SubHour || op == Token::SubDay || op == Token::SubWeek || op == Token::SubYear; }
- constexpr bool isReservedKeyword(Token op) { return (Token::Abstract <= op && op <= Token::Unchecked); }
-
- inline Token AssignmentToBinaryOp(Token op)
- {
- solAssert(isAssignmentOp(op) && op != Token::Assign, "");
- return static_cast<Token>(static_cast<int>(op) + (static_cast<int>(Token::BitOr) - static_cast<int>(Token::AssignBitOr)));
- }
-
- // @returns the precedence > 0 for binary and compare
- // operators; returns 0 otherwise.
- int precedence(Token tok);
-
- std::tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(std::string const& _literal);
-
- // @returns a string corresponding to the C++ token name
- // (e.g. "LT" for the token LT).
- char const* name(Token tok);
-
- // @returns a string corresponding to the JS token string
- // (.e., "<" for the token LT) or NULL if the token doesn't
- // have a (unique) string (e.g. an IDENTIFIER).
- char const* toString(Token tok);
-
- std::string friendlyName(Token tok);
-}
-
-inline std::ostream& operator<<(std::ostream& os, Token token)
-{
- os << TokenTraits::friendlyName(token);
- return os;
-}
-
-class ElementaryTypeNameToken
-{
-public:
- ElementaryTypeNameToken(Token _token, unsigned const& _firstNumber, unsigned const& _secondNumber)
- {
- assertDetails(_token, _firstNumber, _secondNumber);
- }
-
- unsigned int firstNumber() const { return m_firstNumber; }
- unsigned int secondNumber() const { return m_secondNumber; }
- Token token() const { return m_token; }
-
- ///if tokValue is set to true, then returns the actual token type name, otherwise, returns full type
- std::string toString(bool const& tokenValue = false) const
- {
- std::string name = TokenTraits::toString(m_token);
- if (tokenValue || (firstNumber() == 0 && secondNumber() == 0))
- return name;
- solAssert(name.size() >= 3, "Token name size should be greater than 3. Should not reach here.");
- if (m_token == Token::FixedMxN || m_token == Token::UFixedMxN)
- return name.substr(0, name.size() - 3) + std::to_string(m_firstNumber) + "x" + std::to_string(m_secondNumber);
- else
- return name.substr(0, name.size() - 1) + std::to_string(m_firstNumber);
- }
-
-private:
- Token m_token;
- unsigned int m_firstNumber;
- unsigned int m_secondNumber;
- /// throws if type is not properly sized
- void assertDetails(Token _baseType, unsigned const& _first, unsigned const& _second);
-};
-
+using ::langutil::Token;
+using ::langutil::ElementaryTypeNameToken;
}
}
diff --git a/libyul/ASTDataForward.h b/libyul/ASTDataForward.h
deleted file mode 100644
index 8c49e68f..00000000
--- a/libyul/ASTDataForward.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- 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 <http://www.gnu.org/licenses/>.
-*/
-/**
- * @date 2017
- * Pull in some identifiers from the solidity::assembly namespace.
- */
-
-#pragma once
-
-#include <libsolidity/inlineasm/AsmDataForward.h>
-
-namespace dev
-{
-namespace yul
-{
-
-using Instruction = solidity::assembly::Instruction;
-using Literal = solidity::assembly::Literal;
-using Label = solidity::assembly::Label;
-using StackAssignment = solidity::assembly::StackAssignment;
-using Identifier = solidity::assembly::Identifier;
-using Assignment = solidity::assembly::Assignment;
-using VariableDeclaration = solidity::assembly::VariableDeclaration;
-using FunctionalInstruction = solidity::assembly::FunctionalInstruction;
-using FunctionDefinition = solidity::assembly::FunctionDefinition;
-using FunctionCall = solidity::assembly::FunctionCall;
-using If = solidity::assembly::If;
-using Case = solidity::assembly::Case;
-using Switch = solidity::assembly::Switch;
-using ForLoop = solidity::assembly::ForLoop;
-using ExpressionStatement = solidity::assembly::ExpressionStatement;
-using Block = solidity::assembly::Block;
-
-using TypedName = solidity::assembly::TypedName;
-class YulString;
-
-using Expression = boost::variant<FunctionalInstruction, FunctionCall, Identifier, Literal>;
-using Statement = boost::variant<ExpressionStatement, Instruction, Label, StackAssignment, Assignment, VariableDeclaration, FunctionDefinition, If, Switch, ForLoop, Block>;
-
-}
-}
diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp
index ac019c06..d3f6de84 100644
--- a/libsolidity/inlineasm/AsmAnalysis.cpp
+++ b/libyul/AsmAnalysis.cpp
@@ -18,14 +18,14 @@
* Analyzer part of inline assembly.
*/
-#include <libsolidity/inlineasm/AsmAnalysis.h>
+#include <libyul/AsmAnalysis.h>
-#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/inlineasm/AsmScopeFiller.h>
-#include <libsolidity/inlineasm/AsmScope.h>
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
+#include <libyul/AsmData.h>
+#include <libyul/AsmScopeFiller.h>
+#include <libyul/AsmScope.h>
+#include <libyul/AsmAnalysisInfo.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/algorithm/string.hpp>
@@ -35,8 +35,10 @@
using namespace std;
using namespace dev;
+using namespace langutil;
+using namespace yul;
+using namespace dev;
using namespace dev::solidity;
-using namespace dev::solidity::assembly;
namespace {
@@ -64,7 +66,7 @@ bool AsmAnalyzer::operator()(Label const& _label)
return true;
}
-bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction)
+bool AsmAnalyzer::operator()(yul::Instruction const& _instruction)
{
checkLooseFeature(
_instruction.location,
@@ -77,11 +79,11 @@ bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction)
return true;
}
-bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
+bool AsmAnalyzer::operator()(Literal const& _literal)
{
expectValidType(_literal.type.str(), _literal.location);
++m_stackHeight;
- if (_literal.kind == assembly::LiteralKind::String && _literal.value.str().size() > 32)
+ if (_literal.kind == LiteralKind::String && _literal.value.str().size() > 32)
{
m_errorReporter.typeError(
_literal.location,
@@ -89,7 +91,7 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
);
return false;
}
- else if (_literal.kind == assembly::LiteralKind::Number && bigint(_literal.value.str()) > u256(-1))
+ else if (_literal.kind == LiteralKind::Number && bigint(_literal.value.str()) > u256(-1))
{
m_errorReporter.typeError(
_literal.location,
@@ -97,7 +99,7 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
);
return false;
}
- else if (_literal.kind == assembly::LiteralKind::Boolean)
+ else if (_literal.kind == LiteralKind::Boolean)
{
solAssert(m_flavour == AsmFlavour::Yul, "");
solAssert(_literal.value == YulString{string("true")} || _literal.value == YulString{string("false")}, "");
@@ -106,7 +108,7 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal)
return true;
}
-bool AsmAnalyzer::operator()(assembly::Identifier const& _identifier)
+bool AsmAnalyzer::operator()(Identifier const& _identifier)
{
solAssert(!_identifier.name.empty(), "");
size_t numErrorsBefore = m_errorReporter.errors().size();
@@ -176,7 +178,7 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr)
return success;
}
-bool AsmAnalyzer::operator()(assembly::ExpressionStatement const& _statement)
+bool AsmAnalyzer::operator()(ExpressionStatement const& _statement)
{
int initialStackHeight = m_stackHeight;
bool success = boost::apply_visitor(*this, _statement.expression);
@@ -197,7 +199,7 @@ bool AsmAnalyzer::operator()(assembly::ExpressionStatement const& _statement)
return success;
}
-bool AsmAnalyzer::operator()(assembly::StackAssignment const& _assignment)
+bool AsmAnalyzer::operator()(StackAssignment const& _assignment)
{
checkLooseFeature(
_assignment.location,
@@ -208,7 +210,7 @@ bool AsmAnalyzer::operator()(assembly::StackAssignment const& _assignment)
return success;
}
-bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment)
+bool AsmAnalyzer::operator()(Assignment const& _assignment)
{
solAssert(_assignment.value, "");
int const expectedItems = _assignment.variableNames.size();
@@ -234,7 +236,7 @@ bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment)
return success;
}
-bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl)
+bool AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
{
bool success = true;
int const numVariables = _varDecl.variables.size();
@@ -260,7 +262,7 @@ bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl)
return success;
}
-bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef)
+bool AsmAnalyzer::operator()(FunctionDefinition const& _funDef)
{
solAssert(!_funDef.name.empty(), "");
Block const* virtualBlock = m_info.virtualBlocks.at(&_funDef).get();
@@ -282,7 +284,7 @@ bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef)
return success;
}
-bool AsmAnalyzer::operator()(assembly::FunctionCall const& _funCall)
+bool AsmAnalyzer::operator()(FunctionCall const& _funCall)
{
solAssert(!_funCall.functionName.name.empty(), "");
bool success = true;
@@ -396,7 +398,7 @@ bool AsmAnalyzer::operator()(Switch const& _switch)
return success;
}
-bool AsmAnalyzer::operator()(assembly::ForLoop const& _for)
+bool AsmAnalyzer::operator()(ForLoop const& _for)
{
solAssert(_for.condition, "");
@@ -485,7 +487,7 @@ bool AsmAnalyzer::expectDeposit(int _deposit, int _oldHeight, SourceLocation con
return true;
}
-bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t _valueSize)
+bool AsmAnalyzer::checkAssignment(Identifier const& _variable, size_t _valueSize)
{
solAssert(!_variable.name.empty(), "");
bool success = true;
diff --git a/libsolidity/inlineasm/AsmAnalysis.h b/libyul/AsmAnalysis.h
index a8673efa..34e32eb0 100644
--- a/libsolidity/inlineasm/AsmAnalysis.h
+++ b/libyul/AsmAnalysis.h
@@ -20,14 +20,14 @@
#pragma once
-#include <libsolidity/interface/Exceptions.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/Exceptions.h>
+#include <liblangutil/EVMVersion.h>
-#include <libsolidity/inlineasm/AsmScope.h>
+#include <libyul/AsmScope.h>
#include <libyul/backends/evm/AbstractAssembly.h>
-#include <libsolidity/inlineasm/AsmDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
@@ -35,12 +35,13 @@
#include <functional>
#include <memory>
-namespace dev
-{
-namespace solidity
+namespace langutil
{
class ErrorReporter;
-namespace assembly
+struct SourceLocation;
+}
+
+namespace yul
{
struct AsmAnalysisInfo;
@@ -55,11 +56,11 @@ class AsmAnalyzer: public boost::static_visitor<bool>
public:
explicit AsmAnalyzer(
AsmAnalysisInfo& _analysisInfo,
- ErrorReporter& _errorReporter,
- EVMVersion _evmVersion,
- boost::optional<Error::Type> _errorTypeForLoose,
+ langutil::ErrorReporter& _errorReporter,
+ dev::solidity::EVMVersion _evmVersion,
+ boost::optional<langutil::Error::Type> _errorTypeForLoose,
AsmFlavour _flavour = AsmFlavour::Loose,
- yul::ExternalIdentifierAccess::Resolver const& _resolver = yul::ExternalIdentifierAccess::Resolver()
+ ExternalIdentifierAccess::Resolver const& _resolver = ExternalIdentifierAccess::Resolver()
):
m_resolver(_resolver),
m_info(_analysisInfo),
@@ -69,41 +70,41 @@ public:
m_errorTypeForLoose(_errorTypeForLoose)
{}
- bool analyze(assembly::Block const& _block);
-
- bool operator()(assembly::Instruction const&);
- bool operator()(assembly::Literal const& _literal);
- bool operator()(assembly::Identifier const&);
- bool operator()(assembly::FunctionalInstruction const& _functionalInstruction);
- bool operator()(assembly::Label const& _label);
- bool operator()(assembly::ExpressionStatement const&);
- bool operator()(assembly::StackAssignment const&);
- bool operator()(assembly::Assignment const& _assignment);
- bool operator()(assembly::VariableDeclaration const& _variableDeclaration);
- bool operator()(assembly::FunctionDefinition const& _functionDefinition);
- bool operator()(assembly::FunctionCall const& _functionCall);
- bool operator()(assembly::If const& _if);
- bool operator()(assembly::Switch const& _switch);
- bool operator()(assembly::ForLoop const& _forLoop);
- bool operator()(assembly::Block const& _block);
+ bool analyze(Block const& _block);
+
+ bool operator()(Instruction const&);
+ bool operator()(Literal const& _literal);
+ bool operator()(Identifier const&);
+ bool operator()(FunctionalInstruction const& _functionalInstruction);
+ bool operator()(Label const& _label);
+ bool operator()(ExpressionStatement const&);
+ bool operator()(StackAssignment const&);
+ bool operator()(Assignment const& _assignment);
+ bool operator()(VariableDeclaration const& _variableDeclaration);
+ bool operator()(FunctionDefinition const& _functionDefinition);
+ bool operator()(FunctionCall const& _functionCall);
+ bool operator()(If const& _if);
+ bool operator()(Switch const& _switch);
+ bool operator()(ForLoop const& _forLoop);
+ bool operator()(Block const& _block);
private:
/// Visits the statement and expects it to deposit one item onto the stack.
bool expectExpression(Expression const& _expr);
- bool expectDeposit(int _deposit, int _oldHeight, SourceLocation const& _location);
+ bool expectDeposit(int _deposit, int _oldHeight, langutil::SourceLocation const& _location);
/// Verifies that a variable to be assigned to exists and has the same size
/// as the value, @a _valueSize, unless that is equal to -1.
- bool checkAssignment(assembly::Identifier const& _assignment, size_t _valueSize = size_t(-1));
+ bool checkAssignment(Identifier const& _assignment, size_t _valueSize = size_t(-1));
- Scope& scope(assembly::Block const* _block);
- void expectValidType(std::string const& type, SourceLocation const& _location);
- void warnOnInstructions(solidity::Instruction _instr, SourceLocation const& _location);
+ Scope& scope(Block const* _block);
+ void expectValidType(std::string const& type, langutil::SourceLocation const& _location);
+ void warnOnInstructions(dev::solidity::Instruction _instr, langutil::SourceLocation const& _location);
/// Depending on @a m_flavour and @a m_errorTypeForLoose, throws an internal compiler
/// exception (if the flavour is not Loose), reports an error/warning
/// (if m_errorTypeForLoose is set) or does nothing.
- void checkLooseFeature(SourceLocation const& _location, std::string const& _description);
+ void checkLooseFeature(langutil::SourceLocation const& _location, std::string const& _description);
int m_stackHeight = 0;
yul::ExternalIdentifierAccess::Resolver m_resolver;
@@ -112,12 +113,10 @@ private:
/// "part of the scope but not yet declared")
std::set<Scope::Variable const*> m_activeVariables;
AsmAnalysisInfo& m_info;
- ErrorReporter& m_errorReporter;
- EVMVersion m_evmVersion;
+ langutil::ErrorReporter& m_errorReporter;
+ dev::solidity::EVMVersion m_evmVersion;
AsmFlavour m_flavour = AsmFlavour::Loose;
- boost::optional<Error::Type> m_errorTypeForLoose;
+ boost::optional<langutil::Error::Type> m_errorTypeForLoose;
};
}
-}
-}
diff --git a/libsolidity/inlineasm/AsmAnalysisInfo.cpp b/libyul/AsmAnalysisInfo.cpp
index 22318b12..450c0f8f 100644
--- a/libsolidity/inlineasm/AsmAnalysisInfo.cpp
+++ b/libyul/AsmAnalysisInfo.cpp
@@ -18,9 +18,9 @@
* Information generated during analyzer part of inline assembly.
*/
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
+#include <libyul/AsmAnalysisInfo.h>
-#include <libsolidity/inlineasm/AsmScope.h>
+#include <libyul/AsmScope.h>
#include <ostream>
diff --git a/libsolidity/inlineasm/AsmAnalysisInfo.h b/libyul/AsmAnalysisInfo.h
index bd3b28c4..08a35ade 100644
--- a/libsolidity/inlineasm/AsmAnalysisInfo.h
+++ b/libyul/AsmAnalysisInfo.h
@@ -20,7 +20,7 @@
#pragma once
-#include <libsolidity/inlineasm/AsmDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <boost/variant.hpp>
@@ -28,11 +28,7 @@
#include <memory>
#include <vector>
-namespace dev
-{
-namespace solidity
-{
-namespace assembly
+namespace yul
{
struct Scope;
@@ -40,13 +36,11 @@ struct Scope;
struct AsmAnalysisInfo
{
using StackHeightInfo = std::map<void const*, int>;
- using Scopes = std::map<assembly::Block const*, std::shared_ptr<Scope>>;
+ using Scopes = std::map<Block const*, std::shared_ptr<Scope>>;
Scopes scopes;
StackHeightInfo stackHeightInfo;
/// Virtual blocks which will be used for scopes for function arguments and return values.
- std::map<FunctionDefinition const*, std::shared_ptr<assembly::Block const>> virtualBlocks;
+ std::map<FunctionDefinition const*, std::shared_ptr<Block const>> virtualBlocks;
};
}
-}
-}
diff --git a/libsolidity/inlineasm/AsmCodeGen.cpp b/libyul/AsmCodeGen.cpp
index 3a62b232..23bf395d 100644
--- a/libsolidity/inlineasm/AsmCodeGen.cpp
+++ b/libyul/AsmCodeGen.cpp
@@ -20,20 +20,21 @@
* Code-generating part of inline assembly.
*/
-#include <libsolidity/inlineasm/AsmCodeGen.h>
+#include <libyul/AsmCodeGen.h>
-#include <libsolidity/inlineasm/AsmParser.h>
-#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/inlineasm/AsmScope.h>
-#include <libsolidity/inlineasm/AsmAnalysis.h>
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
+#include <libyul/AsmParser.h>
+#include <libyul/AsmData.h>
+#include <libyul/AsmScope.h>
+#include <libyul/AsmAnalysis.h>
+#include <libyul/AsmAnalysisInfo.h>
+
+#include <libyul/backends/evm/AbstractAssembly.h>
+#include <libyul/backends/evm/EVMCodeTransform.h>
#include <libevmasm/Assembly.h>
-#include <libevmasm/SourceLocation.h>
#include <libevmasm/Instruction.h>
-#include <libyul/backends/evm/AbstractAssembly.h>
-#include <libyul/backends/evm/EVMCodeTransform.h>
+#include <liblangutil/SourceLocation.h>
#include <libdevcore/CommonIO.h>
@@ -46,10 +47,11 @@
using namespace std;
using namespace dev;
+using namespace langutil;
+using namespace yul;
using namespace dev::solidity;
-using namespace dev::solidity::assembly;
-class EthAssemblyAdapter: public yul::AbstractAssembly
+class EthAssemblyAdapter: public AbstractAssembly
{
public:
explicit EthAssemblyAdapter(eth::Assembly& _assembly):
@@ -141,16 +143,16 @@ private:
eth::Assembly& m_assembly;
};
-void assembly::CodeGenerator::assemble(
+void CodeGenerator::assemble(
Block const& _parsedData,
AsmAnalysisInfo& _analysisInfo,
eth::Assembly& _assembly,
- yul::ExternalIdentifierAccess const& _identifierAccess,
+ ExternalIdentifierAccess const& _identifierAccess,
bool _useNamedLabelsForFunctions
)
{
EthAssemblyAdapter assemblyAdapter(_assembly);
- yul::CodeTransform(
+ CodeTransform(
assemblyAdapter,
_analysisInfo,
false,
diff --git a/libsolidity/inlineasm/AsmCodeGen.h b/libyul/AsmCodeGen.h
index bbc31397..fd5ac0a1 100644
--- a/libsolidity/inlineasm/AsmCodeGen.h
+++ b/libyul/AsmCodeGen.h
@@ -22,7 +22,7 @@
#pragma once
-#include <libsolidity/inlineasm/AsmAnalysis.h>
+#include <libyul/AsmAnalysis.h>
#include <functional>
@@ -32,9 +32,9 @@ namespace eth
{
class Assembly;
}
-namespace solidity
-{
-namespace assembly
+}
+
+namespace yul
{
struct Block;
@@ -45,12 +45,10 @@ public:
static void assemble(
Block const& _parsedData,
AsmAnalysisInfo& _analysisInfo,
- eth::Assembly& _assembly,
+ dev::eth::Assembly& _assembly,
yul::ExternalIdentifierAccess const& _identifierAccess = yul::ExternalIdentifierAccess(),
bool _useNamedLabelsForFunctions = false
);
};
}
-}
-}
diff --git a/libsolidity/inlineasm/AsmData.h b/libyul/AsmData.h
index a8d5e327..86c373a4 100644
--- a/libsolidity/inlineasm/AsmData.h
+++ b/libyul/AsmData.h
@@ -22,12 +22,11 @@
#pragma once
-#include <libsolidity/inlineasm/AsmDataForward.h>
+#include <libyul/AsmDataForward.h>
+#include <libyul/YulString.h>
#include <libevmasm/Instruction.h>
-#include <libevmasm/SourceLocation.h>
-
-#include <libyul/YulString.h>
+#include <liblangutil/SourceLocation.h>
#include <boost/variant.hpp>
#include <boost/noncopyable.hpp>
@@ -35,70 +34,63 @@
#include <map>
#include <memory>
-namespace dev
-{
-namespace solidity
-{
-namespace assembly
+namespace yul
{
-using YulString = dev::yul::YulString;
using Type = YulString;
-struct TypedName { SourceLocation location; YulString name; Type type; };
+struct TypedName { langutil::SourceLocation location; YulString name; Type type; };
using TypedNameList = std::vector<TypedName>;
/// Direct EVM instruction (except PUSHi and JUMPDEST)
-struct Instruction { SourceLocation location; solidity::Instruction instruction; };
+struct Instruction { langutil::SourceLocation location; dev::solidity::Instruction instruction; };
/// Literal number or string (up to 32 bytes)
enum class LiteralKind { Number, Boolean, String };
-struct Literal { SourceLocation location; LiteralKind kind; YulString value; Type type; };
+struct Literal { langutil::SourceLocation location; LiteralKind kind; YulString value; Type type; };
/// External / internal identifier or label reference
-struct Identifier { SourceLocation location; YulString name; };
+struct Identifier { langutil::SourceLocation location; YulString name; };
/// Jump label ("name:")
-struct Label { SourceLocation location; YulString name; };
+struct Label { langutil::SourceLocation location; YulString name; };
/// Assignment from stack (":= x", moves stack top into x, potentially multiple slots)
-struct StackAssignment { SourceLocation location; Identifier variableName; };
+struct StackAssignment { langutil::SourceLocation location; Identifier variableName; };
/// Assignment ("x := mload(20:u256)", expects push-1-expression on the right hand
/// side and requires x to occupy exactly one stack slot.
///
/// Multiple assignment ("x, y := f()"), where the left hand side variables each occupy
/// a single stack slot and expects a single expression on the right hand returning
/// the same amount of items as the number of variables.
-struct Assignment { SourceLocation location; std::vector<Identifier> variableNames; std::shared_ptr<Expression> value; };
+struct Assignment { langutil::SourceLocation location; std::vector<Identifier> variableNames; std::shared_ptr<Expression> value; };
/// Functional instruction, e.g. "mul(mload(20:u256), add(2:u256, x))"
-struct FunctionalInstruction { SourceLocation location; solidity::Instruction instruction; std::vector<Expression> arguments; };
-struct FunctionCall { SourceLocation location; Identifier functionName; std::vector<Expression> arguments; };
+struct FunctionalInstruction { langutil::SourceLocation location; dev::solidity::Instruction instruction; std::vector<Expression> arguments; };
+struct FunctionCall { langutil::SourceLocation location; Identifier functionName; std::vector<Expression> arguments; };
/// Statement that contains only a single expression
-struct ExpressionStatement { SourceLocation location; Expression expression; };
+struct ExpressionStatement { langutil::SourceLocation location; Expression expression; };
/// Block-scope variable declaration ("let x:u256 := mload(20:u256)"), non-hoisted
-struct VariableDeclaration { SourceLocation location; TypedNameList variables; std::shared_ptr<Expression> value; };
+struct VariableDeclaration { langutil::SourceLocation location; TypedNameList variables; std::shared_ptr<Expression> value; };
/// Block that creates a scope (frees declared stack variables)
-struct Block { SourceLocation location; std::vector<Statement> statements; };
+struct Block { langutil::SourceLocation location; std::vector<Statement> statements; };
/// Function definition ("function f(a, b) -> (d, e) { ... }")
-struct FunctionDefinition { SourceLocation location; YulString name; TypedNameList parameters; TypedNameList returnVariables; Block body; };
+struct FunctionDefinition { langutil::SourceLocation location; YulString name; TypedNameList parameters; TypedNameList returnVariables; Block body; };
/// Conditional execution without "else" part.
-struct If { SourceLocation location; std::shared_ptr<Expression> condition; Block body; };
+struct If { langutil::SourceLocation location; std::shared_ptr<Expression> condition; Block body; };
/// Switch case or default case
-struct Case { SourceLocation location; std::shared_ptr<Literal> value; Block body; };
+struct Case { langutil::SourceLocation location; std::shared_ptr<Literal> value; Block body; };
/// Switch statement
-struct Switch { SourceLocation location; std::shared_ptr<Expression> expression; std::vector<Case> cases; };
-struct ForLoop { SourceLocation location; Block pre; std::shared_ptr<Expression> condition; Block post; Block body; };
+struct Switch { langutil::SourceLocation location; std::shared_ptr<Expression> expression; std::vector<Case> cases; };
+struct ForLoop { langutil::SourceLocation location; Block pre; std::shared_ptr<Expression> condition; Block post; Block body; };
-struct LocationExtractor: boost::static_visitor<SourceLocation>
+struct LocationExtractor: boost::static_visitor<langutil::SourceLocation>
{
- template <class T> SourceLocation operator()(T const& _node) const
+ template <class T> langutil::SourceLocation operator()(T const& _node) const
{
return _node.location;
}
};
/// Extracts the source location from an inline assembly node.
-template <class T> inline SourceLocation locationOf(T const& _node)
+template <class T> inline langutil::SourceLocation locationOf(T const& _node)
{
return boost::apply_visitor(LocationExtractor(), _node);
}
}
-}
-}
diff --git a/libsolidity/inlineasm/AsmDataForward.h b/libyul/AsmDataForward.h
index 69cf8f1d..046c8248 100644
--- a/libsolidity/inlineasm/AsmDataForward.h
+++ b/libyul/AsmDataForward.h
@@ -24,11 +24,7 @@
#include <boost/variant.hpp>
-namespace dev
-{
-namespace solidity
-{
-namespace assembly
+namespace yul
{
struct Instruction;
@@ -61,5 +57,3 @@ enum class AsmFlavour
};
}
-}
-}
diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libyul/AsmParser.cpp
index 1f399edc..2ce94f85 100644
--- a/libsolidity/inlineasm/AsmParser.cpp
+++ b/libyul/AsmParser.cpp
@@ -20,9 +20,9 @@
* Solidity inline assembly parser.
*/
-#include <libsolidity/inlineasm/AsmParser.h>
-#include <libsolidity/parsing/Scanner.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <libyul/AsmParser.h>
+#include <liblangutil/Scanner.h>
+#include <liblangutil/ErrorReporter.h>
#include <boost/algorithm/string.hpp>
@@ -31,10 +31,11 @@
using namespace std;
using namespace dev;
+using namespace langutil;
+using namespace yul;
using namespace dev::solidity;
-using namespace dev::solidity::assembly;
-shared_ptr<assembly::Block> Parser::parse(std::shared_ptr<Scanner> const& _scanner, bool _reuseScanner)
+shared_ptr<Block> Parser::parse(std::shared_ptr<Scanner> const& _scanner, bool _reuseScanner)
{
m_recursionDepth = 0;
try
@@ -53,10 +54,10 @@ shared_ptr<assembly::Block> Parser::parse(std::shared_ptr<Scanner> const& _scann
return nullptr;
}
-assembly::Block Parser::parseBlock()
+Block Parser::parseBlock()
{
RecursionGuard recursionGuard(*this);
- assembly::Block block = createWithLocation<Block>();
+ Block block = createWithLocation<Block>();
expectToken(Token::LBrace);
while (currentToken() != Token::RBrace)
block.statements.emplace_back(parseStatement());
@@ -65,7 +66,7 @@ assembly::Block Parser::parseBlock()
return block;
}
-assembly::Statement Parser::parseStatement()
+Statement Parser::parseStatement()
{
RecursionGuard recursionGuard(*this);
switch (currentToken())
@@ -78,7 +79,7 @@ assembly::Statement Parser::parseStatement()
return parseBlock();
case Token::If:
{
- assembly::If _if = createWithLocation<assembly::If>();
+ If _if = createWithLocation<If>();
m_scanner->next();
_if.condition = make_shared<Expression>(parseExpression());
_if.body = parseBlock();
@@ -86,7 +87,7 @@ assembly::Statement Parser::parseStatement()
}
case Token::Switch:
{
- assembly::Switch _switch = createWithLocation<assembly::Switch>();
+ Switch _switch = createWithLocation<Switch>();
m_scanner->next();
_switch.expression = make_shared<Expression>(parseExpression());
while (m_scanner->currentToken() == Token::Case)
@@ -108,7 +109,7 @@ assembly::Statement Parser::parseStatement()
{
if (m_flavour != AsmFlavour::Loose)
break;
- assembly::StackAssignment assignment = createWithLocation<assembly::StackAssignment>();
+ StackAssignment assignment = createWithLocation<StackAssignment>();
advance();
expectToken(Token::Colon);
assignment.variableName.location = location();
@@ -138,9 +139,9 @@ assembly::Statement Parser::parseStatement()
{
// if a comma follows, a multiple assignment is assumed
- if (elementary.type() != typeid(assembly::Identifier))
+ if (elementary.type() != typeid(Identifier))
fatalParserError("Label name / variable name must precede \",\" (multiple assignment).");
- assembly::Identifier const& identifier = boost::get<assembly::Identifier>(elementary);
+ Identifier const& identifier = boost::get<Identifier>(elementary);
Assignment assignment = createWithLocation<Assignment>(identifier.location);
assignment.variableNames.emplace_back(identifier);
@@ -149,9 +150,9 @@ assembly::Statement Parser::parseStatement()
{
expectToken(Token::Comma);
elementary = parseElementaryOperation();
- if (elementary.type() != typeid(assembly::Identifier))
+ if (elementary.type() != typeid(Identifier))
fatalParserError("Variable name expected in multiple assignment.");
- assignment.variableNames.emplace_back(boost::get<assembly::Identifier>(elementary));
+ assignment.variableNames.emplace_back(boost::get<Identifier>(elementary));
}
while (currentToken() == Token::Comma);
@@ -164,15 +165,15 @@ assembly::Statement Parser::parseStatement()
}
case Token::Colon:
{
- if (elementary.type() != typeid(assembly::Identifier))
+ if (elementary.type() != typeid(Identifier))
fatalParserError("Label name / variable name must precede \":\".");
- assembly::Identifier const& identifier = boost::get<assembly::Identifier>(elementary);
+ Identifier const& identifier = boost::get<Identifier>(elementary);
advance();
// identifier:=: should be parsed as identifier: =: (i.e. a label),
// while identifier:= (being followed by a non-colon) as identifier := (assignment).
if (currentToken() == Token::Assign && peekNextToken() != Token::Colon)
{
- assembly::Assignment assignment = createWithLocation<assembly::Assignment>(identifier.location);
+ Assignment assignment = createWithLocation<Assignment>(identifier.location);
if (m_flavour != AsmFlavour::Yul && instructions().count(identifier.name.str()))
fatalParserError("Cannot use instruction names for identifier names.");
advance();
@@ -196,36 +197,36 @@ assembly::Statement Parser::parseStatement()
fatalParserError("Call or assignment expected.");
break;
}
- if (elementary.type() == typeid(assembly::Identifier))
+ if (elementary.type() == typeid(Identifier))
{
- Expression expr = boost::get<assembly::Identifier>(elementary);
+ Expression expr = boost::get<Identifier>(elementary);
return ExpressionStatement{locationOf(expr), expr};
}
- else if (elementary.type() == typeid(assembly::Literal))
+ else if (elementary.type() == typeid(Literal))
{
- Expression expr = boost::get<assembly::Literal>(elementary);
+ Expression expr = boost::get<Literal>(elementary);
return ExpressionStatement{locationOf(expr), expr};
}
else
{
- solAssert(elementary.type() == typeid(assembly::Instruction), "Invalid elementary operation.");
- return boost::get<assembly::Instruction>(elementary);
+ solAssert(elementary.type() == typeid(Instruction), "Invalid elementary operation.");
+ return boost::get<Instruction>(elementary);
}
}
-assembly::Case Parser::parseCase()
+Case Parser::parseCase()
{
RecursionGuard recursionGuard(*this);
- assembly::Case _case = createWithLocation<assembly::Case>();
+ Case _case = createWithLocation<Case>();
if (m_scanner->currentToken() == Token::Default)
m_scanner->next();
else if (m_scanner->currentToken() == Token::Case)
{
m_scanner->next();
ElementaryOperation literal = parseElementaryOperation();
- if (literal.type() != typeid(assembly::Literal))
+ if (literal.type() != typeid(Literal))
fatalParserError("Literal expected.");
- _case.value = make_shared<Literal>(boost::get<assembly::Literal>(std::move(literal)));
+ _case.value = make_shared<Literal>(boost::get<Literal>(std::move(literal)));
}
else
fatalParserError("Case or default case expected.");
@@ -234,7 +235,7 @@ assembly::Case Parser::parseCase()
return _case;
}
-assembly::ForLoop Parser::parseForLoop()
+ForLoop Parser::parseForLoop()
{
RecursionGuard recursionGuard(*this);
ForLoop forLoop = createWithLocation<ForLoop>();
@@ -247,7 +248,7 @@ assembly::ForLoop Parser::parseForLoop()
return forLoop;
}
-assembly::Expression Parser::parseExpression()
+Expression Parser::parseExpression()
{
RecursionGuard recursionGuard(*this);
// In strict mode, this might parse a plain Instruction, but
@@ -292,12 +293,12 @@ assembly::Expression Parser::parseExpression()
Instruction& instr = boost::get<Instruction>(operation);
return FunctionalInstruction{std::move(instr.location), instr.instruction, {}};
}
- else if (operation.type() == typeid(assembly::Identifier))
- return boost::get<assembly::Identifier>(operation);
+ else if (operation.type() == typeid(Identifier))
+ return boost::get<Identifier>(operation);
else
{
- solAssert(operation.type() == typeid(assembly::Literal), "");
- return boost::get<assembly::Literal>(operation);
+ solAssert(operation.type() == typeid(Literal), "");
+ return boost::get<Literal>(operation);
}
}
@@ -419,7 +420,7 @@ Parser::ElementaryOperation Parser::parseElementaryOperation()
return ret;
}
-assembly::VariableDeclaration Parser::parseVariableDeclaration()
+VariableDeclaration Parser::parseVariableDeclaration()
{
RecursionGuard recursionGuard(*this);
VariableDeclaration varDecl = createWithLocation<VariableDeclaration>();
@@ -444,7 +445,7 @@ assembly::VariableDeclaration Parser::parseVariableDeclaration()
return varDecl;
}
-assembly::FunctionDefinition Parser::parseFunctionDefinition()
+FunctionDefinition Parser::parseFunctionDefinition()
{
RecursionGuard recursionGuard(*this);
FunctionDefinition funDef = createWithLocation<FunctionDefinition>();
@@ -476,7 +477,7 @@ assembly::FunctionDefinition Parser::parseFunctionDefinition()
return funDef;
}
-assembly::Expression Parser::parseCall(Parser::ElementaryOperation&& _initialOp)
+Expression Parser::parseCall(Parser::ElementaryOperation&& _initialOp)
{
RecursionGuard recursionGuard(*this);
if (_initialOp.type() == typeid(Instruction))
diff --git a/libsolidity/inlineasm/AsmParser.h b/libyul/AsmParser.h
index 41117228..cea3b667 100644
--- a/libsolidity/inlineasm/AsmParser.h
+++ b/libyul/AsmParser.h
@@ -24,32 +24,30 @@
#include <memory>
#include <vector>
-#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/parsing/ParserBase.h>
+#include <libyul/AsmData.h>
+#include <liblangutil/SourceLocation.h>
+#include <liblangutil/Scanner.h>
+#include <liblangutil/ParserBase.h>
-namespace dev
-{
-namespace solidity
-{
-namespace assembly
+namespace yul
{
-class Parser: public ParserBase
+class Parser: public langutil::ParserBase
{
public:
- explicit Parser(ErrorReporter& _errorReporter, AsmFlavour _flavour = AsmFlavour::Loose):
+ explicit Parser(langutil::ErrorReporter& _errorReporter, AsmFlavour _flavour = AsmFlavour::Loose):
ParserBase(_errorReporter), m_flavour(_flavour) {}
/// Parses an inline assembly block starting with `{` and ending with `}`.
/// @param _reuseScanner if true, do check for end of input after the `}`.
/// @returns an empty shared pointer on error.
- std::shared_ptr<Block> parse(std::shared_ptr<Scanner> const& _scanner, bool _reuseScanner);
+ std::shared_ptr<Block> parse(std::shared_ptr<langutil::Scanner> const& _scanner, bool _reuseScanner);
protected:
- using ElementaryOperation = boost::variant<assembly::Instruction, assembly::Literal, assembly::Identifier>;
+ using ElementaryOperation = boost::variant<Instruction, Literal, Identifier>;
/// Creates an inline assembly node with the given source location.
- template <class T> T createWithLocation(SourceLocation const& _loc = SourceLocation()) const
+ template <class T> T createWithLocation(langutil::SourceLocation const& _loc = {}) const
{
T r;
r.location = _loc;
@@ -62,14 +60,14 @@ protected:
r.location.sourceName = sourceName();
return r;
}
- SourceLocation location() const { return SourceLocation(position(), endPosition(), sourceName()); }
+ langutil::SourceLocation location() const { return {position(), endPosition(), sourceName()}; }
Block parseBlock();
Statement parseStatement();
Case parseCase();
ForLoop parseForLoop();
/// Parses a functional expression that has to push exactly one stack element
- assembly::Expression parseExpression();
+ Expression parseExpression();
static std::map<std::string, dev::solidity::Instruction> const& instructions();
static std::map<dev::solidity::Instruction, std::string> const& instructionNames();
/// Parses an elementary operation, i.e. a literal, identifier or instruction.
@@ -78,7 +76,7 @@ protected:
ElementaryOperation parseElementaryOperation();
VariableDeclaration parseVariableDeclaration();
FunctionDefinition parseFunctionDefinition();
- assembly::Expression parseCall(ElementaryOperation&& _initialOp);
+ Expression parseCall(ElementaryOperation&& _initialOp);
TypedName parseTypedName();
std::string expectAsmIdentifier();
@@ -89,5 +87,3 @@ private:
};
}
-}
-}
diff --git a/libsolidity/inlineasm/AsmPrinter.cpp b/libyul/AsmPrinter.cpp
index ae0bd1eb..eaaba9f3 100644
--- a/libsolidity/inlineasm/AsmPrinter.cpp
+++ b/libyul/AsmPrinter.cpp
@@ -20,9 +20,9 @@
* Converts a parsed assembly into its textual form.
*/
-#include <libsolidity/inlineasm/AsmPrinter.h>
-#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <libyul/AsmPrinter.h>
+#include <libyul/AsmData.h>
+#include <liblangutil/Exceptions.h>
#include <libdevcore/CommonData.h>
@@ -35,19 +35,19 @@
using namespace std;
using namespace dev;
+using namespace yul;
using namespace dev::solidity;
-using namespace dev::solidity::assembly;
//@TODO source locations
-string AsmPrinter::operator()(assembly::Instruction const& _instruction)
+string AsmPrinter::operator()(yul::Instruction const& _instruction)
{
solAssert(!m_yul, "");
solAssert(isValidInstruction(_instruction.instruction), "Invalid instruction");
return boost::to_lower_copy(instructionInfo(_instruction.instruction).name);
}
-string AsmPrinter::operator()(assembly::Literal const& _literal)
+string AsmPrinter::operator()(Literal const& _literal)
{
switch (_literal.kind)
{
@@ -90,13 +90,13 @@ string AsmPrinter::operator()(assembly::Literal const& _literal)
return "\"" + out + "\"" + appendTypeName(_literal.type);
}
-string AsmPrinter::operator()(assembly::Identifier const& _identifier)
+string AsmPrinter::operator()(Identifier const& _identifier)
{
solAssert(!_identifier.name.empty(), "Invalid identifier.");
return _identifier.name.str();
}
-string AsmPrinter::operator()(assembly::FunctionalInstruction const& _functionalInstruction)
+string AsmPrinter::operator()(FunctionalInstruction const& _functionalInstruction)
{
solAssert(!m_yul, "");
solAssert(isValidInstruction(_functionalInstruction.instruction), "Invalid instruction");
@@ -114,21 +114,21 @@ string AsmPrinter::operator()(ExpressionStatement const& _statement)
return boost::apply_visitor(*this, _statement.expression);
}
-string AsmPrinter::operator()(assembly::Label const& _label)
+string AsmPrinter::operator()(Label const& _label)
{
solAssert(!m_yul, "");
solAssert(!_label.name.empty(), "Invalid label.");
return _label.name.str() + ":";
}
-string AsmPrinter::operator()(assembly::StackAssignment const& _assignment)
+string AsmPrinter::operator()(StackAssignment const& _assignment)
{
solAssert(!m_yul, "");
solAssert(!_assignment.variableName.name.empty(), "Invalid variable name.");
return "=: " + (*this)(_assignment.variableName);
}
-string AsmPrinter::operator()(assembly::Assignment const& _assignment)
+string AsmPrinter::operator()(Assignment const& _assignment)
{
solAssert(_assignment.variableNames.size() >= 1, "");
string variables = (*this)(_assignment.variableNames.front());
@@ -137,7 +137,7 @@ string AsmPrinter::operator()(assembly::Assignment const& _assignment)
return variables + " := " + boost::apply_visitor(*this, *_assignment.value);
}
-string AsmPrinter::operator()(assembly::VariableDeclaration const& _variableDeclaration)
+string AsmPrinter::operator()(VariableDeclaration const& _variableDeclaration)
{
string out = "let ";
out += boost::algorithm::join(
@@ -154,7 +154,7 @@ string AsmPrinter::operator()(assembly::VariableDeclaration const& _variableDecl
return out;
}
-string AsmPrinter::operator()(assembly::FunctionDefinition const& _functionDefinition)
+string AsmPrinter::operator()(FunctionDefinition const& _functionDefinition)
{
solAssert(!_functionDefinition.name.empty(), "Invalid function name.");
string out = "function " + _functionDefinition.name.str() + "(";
@@ -179,7 +179,7 @@ string AsmPrinter::operator()(assembly::FunctionDefinition const& _functionDefin
return out + "\n" + (*this)(_functionDefinition.body);
}
-string AsmPrinter::operator()(assembly::FunctionCall const& _functionCall)
+string AsmPrinter::operator()(FunctionCall const& _functionCall)
{
return
(*this)(_functionCall.functionName) + "(" +
@@ -210,7 +210,7 @@ string AsmPrinter::operator()(Switch const& _switch)
return out;
}
-string AsmPrinter::operator()(assembly::ForLoop const& _forLoop)
+string AsmPrinter::operator()(ForLoop const& _forLoop)
{
solAssert(_forLoop.condition, "Invalid for loop condition.");
string out = "for ";
diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h
new file mode 100644
index 00000000..61dfc18c
--- /dev/null
+++ b/libyul/AsmPrinter.h
@@ -0,0 +1,62 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @author Christian <c@ethdev.com>
+ * @date 2017
+ * Converts a parsed assembly into its textual form.
+ */
+
+#pragma once
+
+#include <libyul/AsmDataForward.h>
+
+#include <libyul/YulString.h>
+
+#include <boost/variant.hpp>
+
+namespace yul
+{
+
+class AsmPrinter: public boost::static_visitor<std::string>
+{
+public:
+ explicit AsmPrinter(bool _yul = false): m_yul(_yul) {}
+
+ std::string operator()(Instruction const& _instruction);
+ std::string operator()(Literal const& _literal);
+ std::string operator()(Identifier const& _identifier);
+ std::string operator()(FunctionalInstruction const& _functionalInstruction);
+ std::string operator()(ExpressionStatement const& _expr);
+ std::string operator()(Label const& _label);
+ std::string operator()(StackAssignment const& _assignment);
+ std::string operator()(Assignment const& _assignment);
+ std::string operator()(VariableDeclaration const& _variableDeclaration);
+ std::string operator()(FunctionDefinition const& _functionDefinition);
+ std::string operator()(FunctionCall const& _functionCall);
+ std::string operator()(If const& _if);
+ std::string operator()(Switch const& _switch);
+ std::string operator()(ForLoop const& _forLoop);
+ std::string operator()(Block const& _block);
+
+private:
+ std::string formatTypedName(TypedName _variable) const;
+ std::string appendTypeName(YulString _type) const;
+
+ bool m_yul = false;
+};
+
+}
diff --git a/libsolidity/inlineasm/AsmScope.cpp b/libyul/AsmScope.cpp
index 10893b96..b71f2367 100644
--- a/libsolidity/inlineasm/AsmScope.cpp
+++ b/libyul/AsmScope.cpp
@@ -18,13 +18,13 @@
* Scopes for identifiers.
*/
-#include <libsolidity/inlineasm/AsmScope.h>
+#include <libyul/AsmScope.h>
using namespace std;
using namespace dev;
-using namespace dev::solidity::assembly;
+using namespace yul;
-bool Scope::registerLabel(yul::YulString _name)
+bool Scope::registerLabel(YulString _name)
{
if (exists(_name))
return false;
@@ -32,7 +32,7 @@ bool Scope::registerLabel(yul::YulString _name)
return true;
}
-bool Scope::registerVariable(yul::YulString _name, YulType const& _type)
+bool Scope::registerVariable(YulString _name, YulType const& _type)
{
if (exists(_name))
return false;
@@ -42,7 +42,7 @@ bool Scope::registerVariable(yul::YulString _name, YulType const& _type)
return true;
}
-bool Scope::registerFunction(yul::YulString _name, std::vector<YulType> const& _arguments, std::vector<YulType> const& _returns)
+bool Scope::registerFunction(YulString _name, std::vector<YulType> const& _arguments, std::vector<YulType> const& _returns)
{
if (exists(_name))
return false;
@@ -50,7 +50,7 @@ bool Scope::registerFunction(yul::YulString _name, std::vector<YulType> const& _
return true;
}
-Scope::Identifier* Scope::lookup(yul::YulString _name)
+Scope::Identifier* Scope::lookup(YulString _name)
{
bool crossedFunctionBoundary = false;
for (Scope* s = this; s; s = s->superScope)
@@ -70,7 +70,7 @@ Scope::Identifier* Scope::lookup(yul::YulString _name)
return nullptr;
}
-bool Scope::exists(yul::YulString _name) const
+bool Scope::exists(YulString _name) const
{
if (identifiers.count(_name))
return true;
diff --git a/libsolidity/inlineasm/AsmScope.h b/libyul/AsmScope.h
index 65848018..2a8ef49e 100644
--- a/libsolidity/inlineasm/AsmScope.h
+++ b/libyul/AsmScope.h
@@ -20,7 +20,7 @@
#pragma once
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <libyul/YulString.h>
@@ -32,16 +32,12 @@
#include <functional>
#include <memory>
-namespace dev
-{
-namespace solidity
-{
-namespace assembly
+namespace yul
{
struct Scope
{
- using YulType = yul::YulString;
+ using YulType = YulString;
using LabelID = size_t;
struct Variable { YulType type; };
@@ -53,13 +49,13 @@ struct Scope
};
using Identifier = boost::variant<Variable, Label, Function>;
- using Visitor = GenericVisitor<Variable const, Label const, Function const>;
- using NonconstVisitor = GenericVisitor<Variable, Label, Function>;
+ using Visitor = dev::GenericVisitor<Variable const, Label const, Function const>;
+ using NonconstVisitor = dev::GenericVisitor<Variable, Label, Function>;
- bool registerVariable(yul::YulString _name, YulType const& _type);
- bool registerLabel(yul::YulString _name);
+ bool registerVariable(YulString _name, YulType const& _type);
+ bool registerLabel(YulString _name);
bool registerFunction(
- yul::YulString _name,
+ YulString _name,
std::vector<YulType> const& _arguments,
std::vector<YulType> const& _returns
);
@@ -69,12 +65,12 @@ struct Scope
/// will any lookups across assembly boundaries.
/// The pointer will be invalidated if the scope is modified.
/// @param _crossedFunction if true, we already crossed a function boundary during recursive lookup
- Identifier* lookup(yul::YulString _name);
+ Identifier* lookup(YulString _name);
/// Looks up the identifier in this and super scopes (will not find variables across function
/// boundaries and generally stops at assembly boundaries) and calls the visitor, returns
/// false if not found.
template <class V>
- bool lookup(yul::YulString _name, V const& _visitor)
+ bool lookup(YulString _name, V const& _visitor)
{
if (Identifier* id = lookup(_name))
{
@@ -86,7 +82,7 @@ struct Scope
}
/// @returns true if the name exists in this scope or in super scopes (also searches
/// across function and assembly boundaries).
- bool exists(yul::YulString _name) const;
+ bool exists(YulString _name) const;
/// @returns the number of variables directly registered inside the scope.
size_t numberOfVariables() const;
@@ -97,9 +93,7 @@ struct Scope
/// If true, variables from the super scope are not visible here (other identifiers are),
/// but they are still taken into account to prevent shadowing.
bool functionScope = false;
- std::map<yul::YulString, Identifier> identifiers;
+ std::map<YulString, Identifier> identifiers;
};
}
-}
-}
diff --git a/libsolidity/inlineasm/AsmScopeFiller.cpp b/libyul/AsmScopeFiller.cpp
index d1f98083..ee797d6a 100644
--- a/libsolidity/inlineasm/AsmScopeFiller.cpp
+++ b/libyul/AsmScopeFiller.cpp
@@ -18,14 +18,14 @@
* Module responsible for registering identifiers inside their scopes.
*/
-#include <libsolidity/inlineasm/AsmScopeFiller.h>
+#include <libyul/AsmScopeFiller.h>
-#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/inlineasm/AsmScope.h>
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
+#include <libyul/AsmData.h>
+#include <libyul/AsmScope.h>
+#include <libyul/AsmAnalysisInfo.h>
-#include <libsolidity/interface/ErrorReporter.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/ErrorReporter.h>
+#include <liblangutil/Exceptions.h>
#include <libdevcore/CommonData.h>
@@ -36,8 +36,9 @@
using namespace std;
using namespace dev;
+using namespace langutil;
+using namespace yul;
using namespace dev::solidity;
-using namespace dev::solidity::assembly;
ScopeFiller::ScopeFiller(AsmAnalysisInfo& _info, ErrorReporter& _errorReporter):
m_info(_info), m_errorReporter(_errorReporter)
@@ -64,7 +65,7 @@ bool ScopeFiller::operator()(Label const& _item)
return true;
}
-bool ScopeFiller::operator()(assembly::VariableDeclaration const& _varDecl)
+bool ScopeFiller::operator()(VariableDeclaration const& _varDecl)
{
for (auto const& variable: _varDecl.variables)
if (!registerVariable(variable, _varDecl.location, *m_currentScope))
@@ -72,7 +73,7 @@ bool ScopeFiller::operator()(assembly::VariableDeclaration const& _varDecl)
return true;
}
-bool ScopeFiller::operator()(assembly::FunctionDefinition const& _funDef)
+bool ScopeFiller::operator()(FunctionDefinition const& _funDef)
{
bool success = true;
vector<Scope::YulType> arguments;
diff --git a/libsolidity/inlineasm/AsmScopeFiller.h b/libyul/AsmScopeFiller.h
index bb023f61..e8fb88d5 100644
--- a/libsolidity/inlineasm/AsmScopeFiller.h
+++ b/libyul/AsmScopeFiller.h
@@ -20,20 +20,20 @@
#pragma once
-#include <libsolidity/inlineasm/AsmDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <boost/variant.hpp>
#include <functional>
#include <memory>
-namespace dev
-{
-struct SourceLocation;
-namespace solidity
+namespace langutil
{
class ErrorReporter;
-namespace assembly
+struct SourceLocation;
+}
+
+namespace yul
{
struct TypedName;
@@ -47,38 +47,36 @@ struct AsmAnalysisInfo;
class ScopeFiller: public boost::static_visitor<bool>
{
public:
- ScopeFiller(AsmAnalysisInfo& _info, ErrorReporter& _errorReporter);
-
- bool operator()(assembly::Instruction const&) { return true; }
- bool operator()(assembly::Literal const&) { return true; }
- bool operator()(assembly::Identifier const&) { return true; }
- bool operator()(assembly::FunctionalInstruction const&) { return true; }
- bool operator()(assembly::ExpressionStatement const& _expr);
- bool operator()(assembly::Label const& _label);
- bool operator()(assembly::StackAssignment const&) { return true; }
- bool operator()(assembly::Assignment const&) { return true; }
- bool operator()(assembly::VariableDeclaration const& _variableDeclaration);
- bool operator()(assembly::FunctionDefinition const& _functionDefinition);
- bool operator()(assembly::FunctionCall const&) { return true; }
- bool operator()(assembly::If const& _if);
- bool operator()(assembly::Switch const& _switch);
- bool operator()(assembly::ForLoop const& _forLoop);
- bool operator()(assembly::Block const& _block);
+ ScopeFiller(AsmAnalysisInfo& _info, langutil::ErrorReporter& _errorReporter);
+
+ bool operator()(Instruction const&) { return true; }
+ bool operator()(Literal const&) { return true; }
+ bool operator()(Identifier const&) { return true; }
+ bool operator()(FunctionalInstruction const&) { return true; }
+ bool operator()(ExpressionStatement const& _expr);
+ bool operator()(Label const& _label);
+ bool operator()(StackAssignment const&) { return true; }
+ bool operator()(Assignment const&) { return true; }
+ bool operator()(VariableDeclaration const& _variableDeclaration);
+ bool operator()(FunctionDefinition const& _functionDefinition);
+ bool operator()(FunctionCall const&) { return true; }
+ bool operator()(If const& _if);
+ bool operator()(Switch const& _switch);
+ bool operator()(ForLoop const& _forLoop);
+ bool operator()(Block const& _block);
private:
bool registerVariable(
TypedName const& _name,
- SourceLocation const& _location,
+ langutil::SourceLocation const& _location,
Scope& _scope
);
- Scope& scope(assembly::Block const* _block);
+ Scope& scope(Block const* _block);
Scope* m_currentScope = nullptr;
AsmAnalysisInfo& m_info;
- ErrorReporter& m_errorReporter;
+ langutil::ErrorReporter& m_errorReporter;
};
}
-}
-}
diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt
new file mode 100644
index 00000000..8fbea689
--- /dev/null
+++ b/libyul/CMakeLists.txt
@@ -0,0 +1,43 @@
+add_library(yul
+ AsmAnalysis.cpp
+ AsmAnalysisInfo.cpp
+ AsmCodeGen.cpp
+ AsmParser.cpp
+ AsmPrinter.cpp
+ AsmScope.cpp
+ AsmScopeFiller.cpp
+ backends/evm/EVMAssembly.cpp
+ backends/evm/EVMCodeTransform.cpp
+ optimiser/ASTCopier.cpp
+ optimiser/ASTWalker.cpp
+ optimiser/BlockFlattener.cpp
+ optimiser/CommonSubexpressionEliminator.cpp
+ optimiser/DataFlowAnalyzer.cpp
+ optimiser/Disambiguator.cpp
+ optimiser/ExpressionInliner.cpp
+ optimiser/ExpressionJoiner.cpp
+ optimiser/ExpressionSimplifier.cpp
+ optimiser/ExpressionSplitter.cpp
+ optimiser/ForLoopInitRewriter.cpp
+ optimiser/FullInliner.cpp
+ optimiser/FunctionGrouper.cpp
+ optimiser/FunctionHoister.cpp
+ optimiser/InlinableExpressionFunctionFinder.cpp
+ optimiser/MainFunction.cpp
+ optimiser/Metrics.cpp
+ optimiser/NameCollector.cpp
+ optimiser/NameDispenser.cpp
+ optimiser/RedundantAssignEliminator.cpp
+ optimiser/Rematerialiser.cpp
+ optimiser/SSATransform.cpp
+ optimiser/SSAValueTracker.cpp
+ optimiser/Semantics.cpp
+ optimiser/SimplificationRules.cpp
+ optimiser/Substitution.cpp
+ optimiser/Suite.cpp
+ optimiser/SyntacticalEquality.cpp
+ optimiser/UnusedPruner.cpp
+ optimiser/Utilities.cpp
+ optimiser/VarDeclPropagator.cpp
+)
+target_link_libraries(yul PUBLIC devcore)
diff --git a/libyul/Exceptions.h b/libyul/Exceptions.h
index 0c421dbf..e10e53ef 100644
--- a/libyul/Exceptions.h
+++ b/libyul/Exceptions.h
@@ -23,18 +23,15 @@
#include <libdevcore/Exceptions.h>
#include <libdevcore/Assertions.h>
-namespace dev
-{
namespace yul
{
-struct YulException: virtual Exception {};
+struct YulException: virtual dev::Exception {};
struct OptimizerException: virtual YulException {};
struct YulAssertion: virtual YulException {};
/// Assertion that throws an YulAssertion containing the given description if it is not met.
#define yulAssert(CONDITION, DESCRIPTION) \
- assertThrow(CONDITION, ::dev::yul::YulException, DESCRIPTION)
+ assertThrow(CONDITION, ::yul::YulException, DESCRIPTION)
}
-}
diff --git a/libyul/YulString.h b/libyul/YulString.h
index ad900a70..2179c23b 100644
--- a/libyul/YulString.h
+++ b/libyul/YulString.h
@@ -27,8 +27,6 @@
#include <vector>
#include <string>
-namespace dev
-{
namespace yul
{
@@ -130,4 +128,3 @@ private:
};
}
-}
diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h
index d75058f7..97b1d305 100644
--- a/libyul/backends/evm/AbstractAssembly.h
+++ b/libyul/backends/evm/AbstractAssembly.h
@@ -22,24 +22,28 @@
#pragma once
+#include <libdevcore/Common.h>
#include <libdevcore/CommonData.h>
#include <functional>
-namespace dev
+namespace langutil
{
struct SourceLocation;
+}
+
+namespace dev
+{
namespace solidity
{
enum class Instruction: uint8_t;
-namespace assembly
-{
-struct Instruction;
-struct Identifier;
}
}
+
namespace yul
{
+struct Instruction;
+struct Identifier;
///
/// Assembly class that abstracts both the libevmasm assembly and the new Yul assembly.
@@ -52,14 +56,14 @@ public:
virtual ~AbstractAssembly() {}
/// Set a new source location valid starting from the next instruction.
- virtual void setSourceLocation(SourceLocation const& _location) = 0;
+ virtual void setSourceLocation(langutil::SourceLocation const& _location) = 0;
/// Retrieve the current height of the stack. This does not have to be zero
/// at the beginning.
virtual int stackHeight() const = 0;
/// Append an EVM instruction.
- virtual void appendInstruction(solidity::Instruction _instruction) = 0;
+ virtual void appendInstruction(dev::solidity::Instruction _instruction) = 0;
/// Append a constant.
- virtual void appendConstant(u256 const& _constant) = 0;
+ virtual void appendConstant(dev::u256 const& _constant) = 0;
/// Append a label.
virtual void appendLabel(LabelID _labelId) = 0;
/// Append a label reference.
@@ -102,18 +106,15 @@ enum class IdentifierContext { LValue, RValue };
/// to inline assembly (not used in standalone assembly mode).
struct ExternalIdentifierAccess
{
- using Resolver = std::function<size_t(solidity::assembly::Identifier const&, IdentifierContext, bool /*_crossesFunctionBoundary*/)>;
+ using Resolver = std::function<size_t(Identifier const&, IdentifierContext, bool /*_crossesFunctionBoundary*/)>;
/// Resolve an external reference given by the identifier in the given context.
/// @returns the size of the value (number of stack slots) or size_t(-1) if not found.
Resolver resolve;
- using CodeGenerator = std::function<void(solidity::assembly::Identifier const&, IdentifierContext, yul::AbstractAssembly&)>;
+ using CodeGenerator = std::function<void(Identifier const&, IdentifierContext, yul::AbstractAssembly&)>;
/// Generate code for retrieving the value (rvalue context) or storing the value (lvalue context)
/// of an identifier. The code should be appended to the assembly. In rvalue context, the value is supposed
/// to be put onto the stack, in lvalue context, the value is assumed to be at the top of the stack.
CodeGenerator generateCode;
};
-
-
-}
}
diff --git a/libyul/backends/evm/EVMAssembly.cpp b/libyul/backends/evm/EVMAssembly.cpp
index b37a3231..99506317 100644
--- a/libyul/backends/evm/EVMAssembly.cpp
+++ b/libyul/backends/evm/EVMAssembly.cpp
@@ -22,11 +22,12 @@
#include <libevmasm/Instruction.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace langutil;
+using namespace yul;
namespace
{
diff --git a/libyul/backends/evm/EVMAssembly.h b/libyul/backends/evm/EVMAssembly.h
index 556ed5a5..d0a437cc 100644
--- a/libyul/backends/evm/EVMAssembly.h
+++ b/libyul/backends/evm/EVMAssembly.h
@@ -26,8 +26,11 @@
#include <map>
-namespace dev
+namespace langutil
{
+struct SourceLocation;
+}
+
namespace yul
{
@@ -38,55 +41,55 @@ public:
virtual ~EVMAssembly() {}
/// Set a new source location valid starting from the next instruction.
- virtual void setSourceLocation(SourceLocation const& _location) override;
+ void setSourceLocation(langutil::SourceLocation const& _location) override;
/// Retrieve the current height of the stack. This does not have to be zero
/// at the beginning.
- virtual int stackHeight() const override { return m_stackHeight; }
+ int stackHeight() const override { return m_stackHeight; }
/// Append an EVM instruction.
- virtual void appendInstruction(solidity::Instruction _instruction) override;
+ void appendInstruction(dev::solidity::Instruction _instruction) override;
/// Append a constant.
- virtual void appendConstant(u256 const& _constant) override;
+ void appendConstant(dev::u256 const& _constant) override;
/// Append a label.
- virtual void appendLabel(LabelID _labelId) override;
+ void appendLabel(LabelID _labelId) override;
/// Append a label reference.
- virtual void appendLabelReference(LabelID _labelId) override;
+ void appendLabelReference(LabelID _labelId) override;
/// Generate a new unique label.
- virtual LabelID newLabelId() override;
+ LabelID newLabelId() override;
/// Returns a label identified by the given name. Creates it if it does not yet exist.
- virtual LabelID namedLabel(std::string const& _name) override;
+ LabelID namedLabel(std::string const& _name) override;
/// Append a reference to a to-be-linked symbol.
/// Currently, we assume that the value is always a 20 byte number.
- virtual void appendLinkerSymbol(std::string const& _name) override;
+ void appendLinkerSymbol(std::string const& _name) override;
/// Append a jump instruction.
/// @param _stackDiffAfter the stack adjustment after this instruction.
- virtual void appendJump(int _stackDiffAfter) override;
+ void appendJump(int _stackDiffAfter) override;
/// Append a jump-to-immediate operation.
- virtual void appendJumpTo(LabelID _labelId, int _stackDiffAfter) override;
+ void appendJumpTo(LabelID _labelId, int _stackDiffAfter) override;
/// Append a jump-to-if-immediate operation.
- virtual void appendJumpToIf(LabelID _labelId) override;
+ void appendJumpToIf(LabelID _labelId) override;
/// Start a subroutine.
- virtual void appendBeginsub(LabelID _labelId, int _arguments) override;
+ void appendBeginsub(LabelID _labelId, int _arguments) override;
/// Call a subroutine.
- virtual void appendJumpsub(LabelID _labelId, int _arguments, int _returns) override;
+ void appendJumpsub(LabelID _labelId, int _arguments, int _returns) override;
/// Return from a subroutine.
- virtual void appendReturnsub(int _returns, int _stackDiffAfter) override;
+ void appendReturnsub(int _returns, int _stackDiffAfter) override;
/// Append the assembled size as a constant.
- virtual void appendAssemblySize() override;
+ void appendAssemblySize() override;
/// Resolves references inside the bytecode and returns the linker object.
- eth::LinkerObject finalize();
+ dev::eth::LinkerObject finalize();
private:
void setLabelToCurrentPosition(AbstractAssembly::LabelID _labelId);
void appendLabelReferenceInternal(AbstractAssembly::LabelID _labelId);
- void updateReference(size_t pos, size_t size, u256 value);
+ void updateReference(size_t pos, size_t size, dev::u256 value);
bool m_evm15 = false; ///< if true, switch to evm1.5 mode
LabelID m_nextLabelId = 0;
int m_stackHeight = 0;
- bytes m_bytecode;
+ dev::bytes m_bytecode;
std::map<std::string, LabelID> m_namedLabels;
std::map<LabelID, size_t> m_labelPositions;
std::map<size_t, LabelID> m_labelReferences;
@@ -94,4 +97,3 @@ private:
};
}
-}
diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp
index 650a8c0a..12abd754 100644
--- a/libyul/backends/evm/EVMCodeTransform.cpp
+++ b/libyul/backends/evm/EVMCodeTransform.cpp
@@ -20,20 +20,18 @@
#include <libyul/backends/evm/EVMCodeTransform.h>
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmAnalysisInfo.h>
+#include <libyul/AsmData.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <boost/range/adaptor/reversed.hpp>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
using namespace dev::solidity;
-using Scope = dev::solidity::assembly::Scope;
-
void CodeTransform::operator()(VariableDeclaration const& _varDecl)
{
solAssert(m_scope, "");
@@ -147,7 +145,7 @@ void CodeTransform::operator()(FunctionalInstruction const& _instruction)
solAssert(_instruction.arguments.size() == 1, "");
}
m_assembly.setSourceLocation(_instruction.location);
- auto label = labelFromIdentifier(boost::get<assembly::Identifier>(_instruction.arguments.at(0)));
+ auto label = labelFromIdentifier(boost::get<Identifier>(_instruction.arguments.at(0)));
if (isJumpI)
m_assembly.appendJumpToIf(label);
else
@@ -163,7 +161,7 @@ void CodeTransform::operator()(FunctionalInstruction const& _instruction)
checkStackHeight(&_instruction);
}
-void CodeTransform::operator()(assembly::Identifier const& _identifier)
+void CodeTransform::operator()(Identifier const& _identifier)
{
m_assembly.setSourceLocation(_identifier.location);
// First search internals, then externals.
@@ -197,12 +195,12 @@ void CodeTransform::operator()(assembly::Identifier const& _identifier)
checkStackHeight(&_identifier);
}
-void CodeTransform::operator()(assembly::Literal const& _literal)
+void CodeTransform::operator()(Literal const& _literal)
{
m_assembly.setSourceLocation(_literal.location);
- if (_literal.kind == assembly::LiteralKind::Number)
+ if (_literal.kind == LiteralKind::Number)
m_assembly.appendConstant(u256(_literal.value.str()));
- else if (_literal.kind == assembly::LiteralKind::Boolean)
+ else if (_literal.kind == LiteralKind::Boolean)
{
if (_literal.value.str() == "true")
m_assembly.appendConstant(u256(1));
@@ -217,7 +215,7 @@ void CodeTransform::operator()(assembly::Literal const& _literal)
checkStackHeight(&_literal);
}
-void CodeTransform::operator()(assembly::Instruction const& _instruction)
+void CodeTransform::operator()(yul::Instruction const& _instruction)
{
solAssert(!m_evm15 || _instruction.instruction != solidity::Instruction::JUMP, "Bare JUMP instruction used for EVM1.5");
solAssert(!m_evm15 || _instruction.instruction != solidity::Instruction::JUMPI, "Bare JUMPI instruction used for EVM1.5");
@@ -522,7 +520,7 @@ void CodeTransform::generateAssignment(Identifier const& _variableName)
}
}
-int CodeTransform::variableHeightDiff(solidity::assembly::Scope::Variable const& _var, bool _forSwap) const
+int CodeTransform::variableHeightDiff(Scope::Variable const& _var, bool _forSwap) const
{
solAssert(m_context->variableStackHeights.count(&_var), "");
int heightDiff = m_assembly.stackHeight() - m_context->variableStackHeights[&_var];
diff --git a/libyul/backends/evm/EVMCodeTransform.h b/libyul/backends/evm/EVMCodeTransform.h
index c0de8ad6..d559f85a 100644
--- a/libyul/backends/evm/EVMCodeTransform.h
+++ b/libyul/backends/evm/EVMCodeTransform.h
@@ -20,25 +20,21 @@
#include <libyul/backends/evm/EVMAssembly.h>
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
-#include <libsolidity/inlineasm/AsmScope.h>
+#include <libyul/AsmScope.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
-namespace dev
-{
-namespace solidity
+namespace langutil
{
class ErrorReporter;
-namespace assembly
-{
-struct AsmAnalysisInfo;
-}
}
+
namespace yul
{
+struct AsmAnalysisInfo;
class EVMAssembly;
class CodeTransform: public boost::static_visitor<>
@@ -47,8 +43,8 @@ public:
/// Create the code transformer.
/// @param _identifierAccess used to resolve identifiers external to the inline assembly
CodeTransform(
- yul::AbstractAssembly& _assembly,
- solidity::assembly::AsmAnalysisInfo& _analysisInfo,
+ AbstractAssembly& _assembly,
+ AsmAnalysisInfo& _analysisInfo,
bool _yul = false,
bool _evm15 = false,
ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess(),
@@ -69,15 +65,14 @@ public:
protected:
struct Context
{
- using Scope = solidity::assembly::Scope;
std::map<Scope::Label const*, AbstractAssembly::LabelID> labelIDs;
std::map<Scope::Function const*, AbstractAssembly::LabelID> functionEntryIDs;
std::map<Scope::Variable const*, int> variableStackHeights;
};
CodeTransform(
- yul::AbstractAssembly& _assembly,
- solidity::assembly::AsmAnalysisInfo& _analysisInfo,
+ AbstractAssembly& _assembly,
+ AsmAnalysisInfo& _analysisInfo,
bool _yul,
bool _evm15,
ExternalIdentifierAccess const& _identifierAccess,
@@ -116,8 +111,8 @@ private:
AbstractAssembly::LabelID labelFromIdentifier(Identifier const& _identifier);
/// @returns the label ID corresponding to the given label, allocating a new one if
/// necessary.
- AbstractAssembly::LabelID labelID(solidity::assembly::Scope::Label const& _label);
- AbstractAssembly::LabelID functionEntryID(YulString _name, solidity::assembly::Scope::Function const& _function);
+ AbstractAssembly::LabelID labelID(Scope::Label const& _label);
+ AbstractAssembly::LabelID functionEntryID(YulString _name, Scope::Function const& _function);
/// Generates code for an expression that is supposed to return a single value.
void visitExpression(Expression const& _expression);
@@ -133,15 +128,15 @@ private:
/// Determines the stack height difference to the given variables. Throws
/// if it is not yet in scope or the height difference is too large. Returns
/// the (positive) stack height difference otherwise.
- int variableHeightDiff(solidity::assembly::Scope::Variable const& _var, bool _forSwap) const;
+ int variableHeightDiff(Scope::Variable const& _var, bool _forSwap) const;
void expectDeposit(int _deposit, int _oldHeight) const;
void checkStackHeight(void const* _astElement) const;
- yul::AbstractAssembly& m_assembly;
- solidity::assembly::AsmAnalysisInfo& m_info;
- solidity::assembly::Scope* m_scope = nullptr;
+ AbstractAssembly& m_assembly;
+ AsmAnalysisInfo& m_info;
+ Scope* m_scope = nullptr;
bool m_yul = false;
bool m_evm15 = false;
bool m_useNamedLabelsForFunctions = false;
@@ -155,4 +150,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/ASTCopier.cpp b/libyul/optimiser/ASTCopier.cpp
index d0c8dd45..f18b0e6b 100644
--- a/libyul/optimiser/ASTCopier.cpp
+++ b/libyul/optimiser/ASTCopier.cpp
@@ -22,13 +22,13 @@
#include <libyul/Exceptions.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/Common.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
Statement ASTCopier::operator()(Instruction const&)
{
diff --git a/libyul/optimiser/ASTCopier.h b/libyul/optimiser/ASTCopier.h
index b6aceee3..4d2f18ae 100644
--- a/libyul/optimiser/ASTCopier.h
+++ b/libyul/optimiser/ASTCopier.h
@@ -20,7 +20,7 @@
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <libyul/YulString.h>
@@ -31,8 +31,6 @@
#include <set>
#include <memory>
-namespace dev
-{
namespace yul
{
@@ -71,21 +69,21 @@ class ASTCopier: public ExpressionCopier, public StatementCopier
{
public:
virtual ~ASTCopier() = default;
- virtual Expression operator()(Literal const& _literal) override;
- virtual Statement operator()(Instruction const& _instruction) override;
- virtual Expression operator()(Identifier const& _identifier) override;
- virtual Expression operator()(FunctionalInstruction const& _instr) override;
- virtual Expression operator()(FunctionCall const&) override;
- virtual Statement operator()(ExpressionStatement const& _statement) override;
- virtual Statement operator()(Label const& _label) override;
- virtual Statement operator()(StackAssignment const& _assignment) override;
- virtual Statement operator()(Assignment const& _assignment) override;
- virtual Statement operator()(VariableDeclaration const& _varDecl) override;
- virtual Statement operator()(If const& _if) override;
- virtual Statement operator()(Switch const& _switch) override;
- virtual Statement operator()(FunctionDefinition const&) override;
- virtual Statement operator()(ForLoop const&) override;
- virtual Statement operator()(Block const& _block) override;
+ Expression operator()(Literal const& _literal) override;
+ Statement operator()(Instruction const& _instruction) override;
+ Expression operator()(Identifier const& _identifier) override;
+ Expression operator()(FunctionalInstruction const& _instr) override;
+ Expression operator()(FunctionCall const&) override;
+ Statement operator()(ExpressionStatement const& _statement) override;
+ Statement operator()(Label const& _label) override;
+ Statement operator()(StackAssignment const& _assignment) override;
+ Statement operator()(Assignment const& _assignment) override;
+ Statement operator()(VariableDeclaration const& _varDecl) override;
+ Statement operator()(If const& _if) override;
+ Statement operator()(Switch const& _switch) override;
+ Statement operator()(FunctionDefinition const&) override;
+ Statement operator()(ForLoop const&) override;
+ Statement operator()(Block const& _block) override;
virtual Expression translate(Expression const& _expression);
virtual Statement translate(Statement const& _statement);
@@ -123,4 +121,3 @@ std::vector<T> ASTCopier::translateVector(std::vector<T> const& _values)
}
-}
diff --git a/libyul/optimiser/ASTWalker.cpp b/libyul/optimiser/ASTWalker.cpp
index e29dda6b..0d568007 100644
--- a/libyul/optimiser/ASTWalker.cpp
+++ b/libyul/optimiser/ASTWalker.cpp
@@ -20,13 +20,13 @@
#include <libyul/optimiser/ASTWalker.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <boost/range/adaptor/reversed.hpp>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
using namespace dev::solidity;
diff --git a/libyul/optimiser/ASTWalker.h b/libyul/optimiser/ASTWalker.h
index 38cb85ea..b59b405e 100644
--- a/libyul/optimiser/ASTWalker.h
+++ b/libyul/optimiser/ASTWalker.h
@@ -20,7 +20,7 @@
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <libyul/Exceptions.h>
#include <libyul/YulString.h>
@@ -32,8 +32,6 @@
#include <set>
#include <map>
-namespace dev
-{
namespace yul
{
@@ -120,4 +118,3 @@ protected:
};
}
-}
diff --git a/libyul/optimiser/BlockFlattener.cpp b/libyul/optimiser/BlockFlattener.cpp
index 04f3ad7f..e6f08524 100644
--- a/libyul/optimiser/BlockFlattener.cpp
+++ b/libyul/optimiser/BlockFlattener.cpp
@@ -15,14 +15,14 @@
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libyul/optimiser/BlockFlattener.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/Visitor.h>
#include <libdevcore/CommonData.h>
#include <functional>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
void BlockFlattener::operator()(Block& _block)
{
diff --git a/libyul/optimiser/BlockFlattener.h b/libyul/optimiser/BlockFlattener.h
index 88c49dda..b732422d 100644
--- a/libyul/optimiser/BlockFlattener.h
+++ b/libyul/optimiser/BlockFlattener.h
@@ -18,8 +18,6 @@
#include <libyul/optimiser/ASTWalker.h>
-namespace dev
-{
namespace yul
{
@@ -31,4 +29,3 @@ public:
};
}
-}
diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp
index 64605362..9b851333 100644
--- a/libyul/optimiser/CommonSubexpressionEliminator.cpp
+++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp
@@ -24,12 +24,11 @@
#include <libyul/optimiser/Metrics.h>
#include <libyul/optimiser/SyntacticalEquality.h>
#include <libyul/Exceptions.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
void CommonSubexpressionEliminator::visit(Expression& _e)
{
diff --git a/libyul/optimiser/CommonSubexpressionEliminator.h b/libyul/optimiser/CommonSubexpressionEliminator.h
index f8aa0ee1..ac1ebe3a 100644
--- a/libyul/optimiser/CommonSubexpressionEliminator.h
+++ b/libyul/optimiser/CommonSubexpressionEliminator.h
@@ -23,8 +23,6 @@
#include <libyul/optimiser/DataFlowAnalyzer.h>
-namespace dev
-{
namespace yul
{
@@ -38,8 +36,7 @@ class CommonSubexpressionEliminator: public DataFlowAnalyzer
{
protected:
using ASTModifier::visit;
- virtual void visit(Expression& _e) override;
+ void visit(Expression& _e) override;
};
}
-}
diff --git a/libyul/optimiser/DataFlowAnalyzer.cpp b/libyul/optimiser/DataFlowAnalyzer.cpp
index 134777d0..64c67b38 100644
--- a/libyul/optimiser/DataFlowAnalyzer.cpp
+++ b/libyul/optimiser/DataFlowAnalyzer.cpp
@@ -25,8 +25,7 @@
#include <libyul/optimiser/NameCollector.h>
#include <libyul/optimiser/Semantics.h>
#include <libyul/Exceptions.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/CommonData.h>
@@ -34,7 +33,7 @@
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
void DataFlowAnalyzer::operator()(Assignment& _assignment)
{
diff --git a/libyul/optimiser/DataFlowAnalyzer.h b/libyul/optimiser/DataFlowAnalyzer.h
index a0c21eee..cd134d48 100644
--- a/libyul/optimiser/DataFlowAnalyzer.h
+++ b/libyul/optimiser/DataFlowAnalyzer.h
@@ -23,14 +23,11 @@
#pragma once
#include <libyul/optimiser/ASTWalker.h>
-
#include <libyul/YulString.h>
#include <map>
#include <set>
-namespace dev
-{
namespace yul
{
@@ -45,13 +42,13 @@ class DataFlowAnalyzer: public ASTModifier
{
public:
using ASTModifier::operator();
- virtual void operator()(Assignment& _assignment) override;
- virtual void operator()(VariableDeclaration& _varDecl) override;
- virtual void operator()(If& _if) override;
- virtual void operator()(Switch& _switch) override;
- virtual void operator()(FunctionDefinition&) override;
- virtual void operator()(ForLoop&) override;
- virtual void operator()(Block& _block) override;
+ void operator()(Assignment& _assignment) override;
+ void operator()(VariableDeclaration& _varDecl) override;
+ void operator()(If& _if) override;
+ void operator()(Switch& _switch) override;
+ void operator()(FunctionDefinition&) override;
+ void operator()(ForLoop&) override;
+ void operator()(Block& _block) override;
protected:
/// Registers the assignment.
@@ -88,4 +85,3 @@ protected:
};
}
-}
diff --git a/libyul/optimiser/Disambiguator.cpp b/libyul/optimiser/Disambiguator.cpp
index 4303f412..fda5895b 100644
--- a/libyul/optimiser/Disambiguator.cpp
+++ b/libyul/optimiser/Disambiguator.cpp
@@ -21,17 +21,14 @@
#include <libyul/optimiser/Disambiguator.h>
#include <libyul/Exceptions.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/inlineasm/AsmScope.h>
+#include <libyul/AsmData.h>
+#include <libyul/AsmScope.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
using namespace dev::solidity;
-using Scope = dev::solidity::assembly::Scope;
-
YulString Disambiguator::translateIdentifier(YulString _originalName)
{
if ((m_externallyUsedIdentifiers.count(_originalName)))
diff --git a/libyul/optimiser/Disambiguator.h b/libyul/optimiser/Disambiguator.h
index bfb65682..bb83417b 100644
--- a/libyul/optimiser/Disambiguator.h
+++ b/libyul/optimiser/Disambiguator.h
@@ -20,20 +20,16 @@
#pragma once
-#include <libyul/ASTDataForward.h>
-
+#include <libyul/AsmDataForward.h>
+#include <libyul/AsmAnalysisInfo.h>
#include <libyul/optimiser/ASTCopier.h>
#include <libyul/optimiser/NameDispenser.h>
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
-
#include <boost/variant.hpp>
#include <boost/optional.hpp>
#include <set>
-namespace dev
-{
namespace yul
{
@@ -44,7 +40,7 @@ class Disambiguator: public ASTCopier
{
public:
explicit Disambiguator(
- solidity::assembly::AsmAnalysisInfo const& _analysisInfo,
+ AsmAnalysisInfo const& _analysisInfo,
std::set<YulString> const& _externallyUsedIdentifiers = {}
):
m_info(_analysisInfo), m_externallyUsedIdentifiers(_externallyUsedIdentifiers), m_nameDispenser(m_externallyUsedIdentifiers)
@@ -52,22 +48,21 @@ public:
}
protected:
- virtual void enterScope(Block const& _block) override;
- virtual void leaveScope(Block const& _block) override;
- virtual void enterFunction(FunctionDefinition const& _function) override;
- virtual void leaveFunction(FunctionDefinition const& _function) override;
- virtual YulString translateIdentifier(YulString _name) override;
+ void enterScope(Block const& _block) override;
+ void leaveScope(Block const& _block) override;
+ void enterFunction(FunctionDefinition const& _function) override;
+ void leaveFunction(FunctionDefinition const& _function) override;
+ YulString translateIdentifier(YulString _name) override;
- void enterScopeInternal(solidity::assembly::Scope& _scope);
- void leaveScopeInternal(solidity::assembly::Scope& _scope);
+ void enterScopeInternal(Scope& _scope);
+ void leaveScopeInternal(Scope& _scope);
- solidity::assembly::AsmAnalysisInfo const& m_info;
+ AsmAnalysisInfo const& m_info;
std::set<YulString> const& m_externallyUsedIdentifiers;
- std::vector<solidity::assembly::Scope*> m_scopes;
+ std::vector<Scope*> m_scopes;
std::map<void const*, YulString> m_translations;
NameDispenser m_nameDispenser;
};
}
-}
diff --git a/libyul/optimiser/ExpressionInliner.cpp b/libyul/optimiser/ExpressionInliner.cpp
index 07e88191..27d43ac0 100644
--- a/libyul/optimiser/ExpressionInliner.cpp
+++ b/libyul/optimiser/ExpressionInliner.cpp
@@ -23,14 +23,13 @@
#include <libyul/optimiser/InlinableExpressionFunctionFinder.h>
#include <libyul/optimiser/Substitution.h>
#include <libyul/optimiser/Semantics.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <boost/algorithm/cxx11/all_of.hpp>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
using namespace dev::solidity;
void ExpressionInliner::run()
diff --git a/libyul/optimiser/ExpressionInliner.h b/libyul/optimiser/ExpressionInliner.h
index d903664f..14e80c0a 100644
--- a/libyul/optimiser/ExpressionInliner.h
+++ b/libyul/optimiser/ExpressionInliner.h
@@ -20,16 +20,13 @@
#pragma once
#include <libyul/optimiser/ASTWalker.h>
-
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
#include <set>
-namespace dev
-{
namespace yul
{
@@ -54,9 +51,9 @@ public:
void run();
using ASTModifier::operator();
- virtual void operator()(FunctionDefinition& _fun) override;
+ void operator()(FunctionDefinition& _fun) override;
- virtual void visit(Expression& _expression) override;
+ void visit(Expression& _expression) override;
private:
std::map<YulString, FunctionDefinition const*> m_inlinableFunctions;
@@ -69,4 +66,3 @@ private:
}
-}
diff --git a/libyul/optimiser/ExpressionJoiner.cpp b/libyul/optimiser/ExpressionJoiner.cpp
index 7e57a629..de2b5d53 100644
--- a/libyul/optimiser/ExpressionJoiner.cpp
+++ b/libyul/optimiser/ExpressionJoiner.cpp
@@ -24,8 +24,7 @@
#include <libyul/optimiser/NameCollector.h>
#include <libyul/optimiser/Utilities.h>
#include <libyul/Exceptions.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/CommonData.h>
@@ -33,7 +32,7 @@
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
using namespace dev::solidity;
void ExpressionJoiner::operator()(FunctionalInstruction& _instruction)
diff --git a/libyul/optimiser/ExpressionJoiner.h b/libyul/optimiser/ExpressionJoiner.h
index 0cc61981..643d62b0 100644
--- a/libyul/optimiser/ExpressionJoiner.h
+++ b/libyul/optimiser/ExpressionJoiner.h
@@ -20,14 +20,11 @@
*/
#pragma once
-#include <libyul/ASTDataForward.h>
-
+#include <libyul/AsmDataForward.h>
#include <libyul/optimiser/ASTWalker.h>
#include <map>
-namespace dev
-{
namespace yul
{
@@ -99,4 +96,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/ExpressionSimplifier.cpp b/libyul/optimiser/ExpressionSimplifier.cpp
index 64e9d7e7..cda44e8e 100644
--- a/libyul/optimiser/ExpressionSimplifier.cpp
+++ b/libyul/optimiser/ExpressionSimplifier.cpp
@@ -23,14 +23,13 @@
#include <libyul/optimiser/SimplificationRules.h>
#include <libyul/optimiser/Semantics.h>
#include <libyul/optimiser/SSAValueTracker.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/CommonData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
using namespace dev::solidity;
diff --git a/libyul/optimiser/ExpressionSimplifier.h b/libyul/optimiser/ExpressionSimplifier.h
index 5965a1bb..fe3507f8 100644
--- a/libyul/optimiser/ExpressionSimplifier.h
+++ b/libyul/optimiser/ExpressionSimplifier.h
@@ -20,12 +20,10 @@
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <libyul/optimiser/ASTWalker.h>
-namespace dev
-{
namespace yul
{
@@ -52,4 +50,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/ExpressionSplitter.cpp b/libyul/optimiser/ExpressionSplitter.cpp
index a4b7a909..a3b2dc11 100644
--- a/libyul/optimiser/ExpressionSplitter.cpp
+++ b/libyul/optimiser/ExpressionSplitter.cpp
@@ -23,7 +23,7 @@
#include <libyul/optimiser/ASTWalker.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/CommonData.h>
@@ -31,7 +31,8 @@
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace langutil;
+using namespace yul;
using namespace dev::solidity;
void ExpressionSplitter::operator()(FunctionalInstruction& _instruction)
diff --git a/libyul/optimiser/ExpressionSplitter.h b/libyul/optimiser/ExpressionSplitter.h
index 339acbf0..d4d2b3f6 100644
--- a/libyul/optimiser/ExpressionSplitter.h
+++ b/libyul/optimiser/ExpressionSplitter.h
@@ -20,15 +20,13 @@
*/
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <libyul/optimiser/ASTWalker.h>
#include <libyul/optimiser/NameDispenser.h>
#include <vector>
-namespace dev
-{
namespace yul
{
@@ -63,12 +61,12 @@ public:
m_nameDispenser(_nameDispenser)
{ }
- virtual void operator()(FunctionalInstruction&) override;
- virtual void operator()(FunctionCall&) override;
- virtual void operator()(If&) override;
- virtual void operator()(Switch&) override;
- virtual void operator()(ForLoop&) override;
- virtual void operator()(Block& _block) override;
+ void operator()(FunctionalInstruction&) override;
+ void operator()(FunctionCall&) override;
+ void operator()(If&) override;
+ void operator()(Switch&) override;
+ void operator()(ForLoop&) override;
+ void operator()(Block& _block) override;
private:
/// Replaces the expression by a variable if it is a function call or functional
@@ -83,4 +81,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/ForLoopInitRewriter.cpp b/libyul/optimiser/ForLoopInitRewriter.cpp
new file mode 100644
index 00000000..80d39248
--- /dev/null
+++ b/libyul/optimiser/ForLoopInitRewriter.cpp
@@ -0,0 +1,43 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#include <libyul/optimiser/ForLoopInitRewriter.h>
+#include <libyul/AsmData.h>
+#include <libdevcore/CommonData.h>
+#include <functional>
+
+using namespace std;
+using namespace dev;
+using namespace yul;
+
+void ForLoopInitRewriter::operator()(Block& _block)
+{
+ iterateReplacing(
+ _block.statements,
+ [](Statement& _stmt) -> boost::optional<vector<Statement>>
+ {
+ if (_stmt.type() == typeid(ForLoop))
+ {
+ auto& forLoop = boost::get<ForLoop>(_stmt);
+ vector<Statement> rewrite;
+ swap(rewrite, forLoop.pre.statements);
+ rewrite.emplace_back(move(forLoop));
+ return rewrite;
+ }
+ return {};
+ }
+ );
+}
diff --git a/libyul/optimiser/ForLoopInitRewriter.h b/libyul/optimiser/ForLoopInitRewriter.h
new file mode 100644
index 00000000..e925c6c2
--- /dev/null
+++ b/libyul/optimiser/ForLoopInitRewriter.h
@@ -0,0 +1,36 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+#pragma once
+
+#include <libyul/optimiser/ASTWalker.h>
+
+namespace yul
+{
+
+/**
+ * Rewrites ForLoop by moving the pre statement block in front of the ForLoop.
+ * Requirements:
+ * - The Disambiguator must be run upfront.
+ */
+class ForLoopInitRewriter: public ASTModifier
+{
+public:
+ using ASTModifier::operator();
+ void operator()(Block& _block) override;
+};
+
+}
diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp
index c9057cf3..8ae26fbb 100644
--- a/libyul/optimiser/FullInliner.cpp
+++ b/libyul/optimiser/FullInliner.cpp
@@ -27,8 +27,7 @@
#include <libyul/optimiser/Metrics.h>
#include <libyul/optimiser/SSAValueTracker.h>
#include <libyul/Exceptions.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/CommonData.h>
#include <libdevcore/Visitor.h>
@@ -37,7 +36,7 @@
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
using namespace dev::solidity;
FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser):
diff --git a/libyul/optimiser/FullInliner.h b/libyul/optimiser/FullInliner.h
index 66ce8e2f..a8fe76c6 100644
--- a/libyul/optimiser/FullInliner.h
+++ b/libyul/optimiser/FullInliner.h
@@ -19,22 +19,20 @@
*/
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <libyul/optimiser/ASTCopier.h>
#include <libyul/optimiser/ASTWalker.h>
#include <libyul/optimiser/NameDispenser.h>
#include <libyul/Exceptions.h>
-#include <libevmasm/SourceLocation.h>
+#include <liblangutil/SourceLocation.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
#include <set>
-namespace dev
-{
namespace yul
{
@@ -110,7 +108,7 @@ public:
m_nameDispenser(_nameDispenser)
{ }
- virtual void operator()(Block& _block) override;
+ void operator()(Block& _block) override;
private:
boost::optional<std::vector<Statement>> tryInlineStatement(Statement& _statement);
@@ -141,10 +139,10 @@ public:
using ASTCopier::operator ();
- virtual Statement operator()(VariableDeclaration const& _varDecl) override;
- virtual Statement operator()(FunctionDefinition const& _funDef) override;
+ Statement operator()(VariableDeclaration const& _varDecl) override;
+ Statement operator()(FunctionDefinition const& _funDef) override;
- virtual YulString translateIdentifier(YulString _name) override;
+ YulString translateIdentifier(YulString _name) override;
NameDispenser& m_nameDispenser;
YulString m_varNamePrefix;
@@ -153,4 +151,3 @@ public:
}
-}
diff --git a/libyul/optimiser/FunctionGrouper.cpp b/libyul/optimiser/FunctionGrouper.cpp
index 3d2e5322..02ce22cd 100644
--- a/libyul/optimiser/FunctionGrouper.cpp
+++ b/libyul/optimiser/FunctionGrouper.cpp
@@ -21,13 +21,13 @@
#include <libyul/optimiser/FunctionGrouper.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <boost/range/algorithm_ext/erase.hpp>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
using namespace dev::solidity;
diff --git a/libyul/optimiser/FunctionGrouper.h b/libyul/optimiser/FunctionGrouper.h
index 63cfbfb1..3b3f48a7 100644
--- a/libyul/optimiser/FunctionGrouper.h
+++ b/libyul/optimiser/FunctionGrouper.h
@@ -21,10 +21,8 @@
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
-namespace dev
-{
namespace yul
{
@@ -43,4 +41,3 @@ public:
};
}
-}
diff --git a/libyul/optimiser/FunctionHoister.cpp b/libyul/optimiser/FunctionHoister.cpp
index c196dead..bd1c781b 100644
--- a/libyul/optimiser/FunctionHoister.cpp
+++ b/libyul/optimiser/FunctionHoister.cpp
@@ -22,14 +22,13 @@
#include <libyul/optimiser/FunctionHoister.h>
#include <libyul/optimiser/Utilities.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/CommonData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
using namespace dev::solidity;
void FunctionHoister::operator()(Block& _block)
diff --git a/libyul/optimiser/FunctionHoister.h b/libyul/optimiser/FunctionHoister.h
index 823b9e2b..31092069 100644
--- a/libyul/optimiser/FunctionHoister.h
+++ b/libyul/optimiser/FunctionHoister.h
@@ -21,12 +21,9 @@
#pragma once
-#include <libyul/ASTDataForward.h>
-
+#include <libyul/AsmDataForward.h>
#include <libyul/optimiser/ASTWalker.h>
-namespace dev
-{
namespace yul
{
@@ -49,4 +46,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/InlinableExpressionFunctionFinder.cpp b/libyul/optimiser/InlinableExpressionFunctionFinder.cpp
index deaaee97..662cdf25 100644
--- a/libyul/optimiser/InlinableExpressionFunctionFinder.cpp
+++ b/libyul/optimiser/InlinableExpressionFunctionFinder.cpp
@@ -21,12 +21,11 @@
#include <libyul/optimiser/InlinableExpressionFunctionFinder.h>
#include <libyul/optimiser/Utilities.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
void InlinableExpressionFunctionFinder::operator()(Identifier const& _identifier)
{
diff --git a/libyul/optimiser/InlinableExpressionFunctionFinder.h b/libyul/optimiser/InlinableExpressionFunctionFinder.h
index baf4bbfc..afde8a2a 100644
--- a/libyul/optimiser/InlinableExpressionFunctionFinder.h
+++ b/libyul/optimiser/InlinableExpressionFunctionFinder.h
@@ -20,13 +20,11 @@
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <libyul/optimiser/ASTWalker.h>
#include <set>
-namespace dev
-{
namespace yul
{
@@ -49,9 +47,9 @@ public:
}
using ASTWalker::operator();
- virtual void operator()(Identifier const& _identifier) override;
- virtual void operator()(FunctionCall const& _funCall) override;
- virtual void operator()(FunctionDefinition const& _function) override;
+ void operator()(Identifier const& _identifier) override;
+ void operator()(FunctionCall const& _funCall) override;
+ void operator()(FunctionDefinition const& _function) override;
private:
void checkAllowed(YulString _name)
@@ -66,4 +64,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/MainFunction.cpp b/libyul/optimiser/MainFunction.cpp
index f3306598..63eea2db 100644
--- a/libyul/optimiser/MainFunction.cpp
+++ b/libyul/optimiser/MainFunction.cpp
@@ -24,13 +24,13 @@
#include <libyul/optimiser/NameCollector.h>
#include <libyul/Exceptions.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/CommonData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
using namespace dev::solidity;
void MainFunction::operator()(Block& _block)
diff --git a/libyul/optimiser/MainFunction.h b/libyul/optimiser/MainFunction.h
index 4a73283a..96acc0ac 100644
--- a/libyul/optimiser/MainFunction.h
+++ b/libyul/optimiser/MainFunction.h
@@ -21,10 +21,8 @@
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
-namespace dev
-{
namespace yul
{
@@ -38,4 +36,3 @@ public:
};
}
-}
diff --git a/libyul/optimiser/Metrics.cpp b/libyul/optimiser/Metrics.cpp
index 066c6b58..a5557fb3 100644
--- a/libyul/optimiser/Metrics.cpp
+++ b/libyul/optimiser/Metrics.cpp
@@ -20,10 +20,10 @@
#include <libyul/optimiser/Metrics.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
size_t CodeSize::codeSize(Statement const& _statement)
{
diff --git a/libyul/optimiser/Metrics.h b/libyul/optimiser/Metrics.h
index 47c7ec79..ca244600 100644
--- a/libyul/optimiser/Metrics.h
+++ b/libyul/optimiser/Metrics.h
@@ -22,8 +22,6 @@
#include <libyul/optimiser/ASTWalker.h>
-namespace dev
-{
namespace yul
{
@@ -41,12 +39,11 @@ public:
static size_t codeSize(Block const& _block);
private:
- virtual void visit(Statement const& _statement) override;
- virtual void visit(Expression const& _expression) override;
+ void visit(Statement const& _statement) override;
+ void visit(Expression const& _expression) override;
private:
size_t m_size = 0;
};
}
-}
diff --git a/libyul/optimiser/NameCollector.cpp b/libyul/optimiser/NameCollector.cpp
index 36f55b99..f9079827 100644
--- a/libyul/optimiser/NameCollector.cpp
+++ b/libyul/optimiser/NameCollector.cpp
@@ -20,11 +20,11 @@
#include <libyul/optimiser/NameCollector.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
void NameCollector::operator()(VariableDeclaration const& _varDecl)
{
diff --git a/libyul/optimiser/NameCollector.h b/libyul/optimiser/NameCollector.h
index b76eec30..c177a399 100644
--- a/libyul/optimiser/NameCollector.h
+++ b/libyul/optimiser/NameCollector.h
@@ -25,8 +25,6 @@
#include <map>
#include <set>
-namespace dev
-{
namespace yul
{
@@ -42,8 +40,8 @@ public:
}
using ASTWalker::operator ();
- virtual void operator()(VariableDeclaration const& _varDecl) override;
- virtual void operator()(FunctionDefinition const& _funDef) override;
+ void operator()(VariableDeclaration const& _varDecl) override;
+ void operator()(FunctionDefinition const& _funDef) override;
std::set<YulString> names() const { return m_names; }
private:
@@ -75,7 +73,7 @@ class Assignments: public ASTWalker
{
public:
using ASTWalker::operator ();
- virtual void operator()(Assignment const& _assignment) override;
+ void operator()(Assignment const& _assignment) override;
std::set<YulString> const& names() const { return m_names; }
private:
@@ -83,4 +81,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/NameDispenser.cpp b/libyul/optimiser/NameDispenser.cpp
index 3c870fa5..e7cdc60f 100644
--- a/libyul/optimiser/NameDispenser.cpp
+++ b/libyul/optimiser/NameDispenser.cpp
@@ -21,12 +21,11 @@
#include <libyul/optimiser/NameDispenser.h>
#include <libyul/optimiser/NameCollector.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
NameDispenser::NameDispenser(Block const& _ast):
NameDispenser(NameCollector(_ast).names())
diff --git a/libyul/optimiser/NameDispenser.h b/libyul/optimiser/NameDispenser.h
index 7311440b..664a5265 100644
--- a/libyul/optimiser/NameDispenser.h
+++ b/libyul/optimiser/NameDispenser.h
@@ -19,14 +19,12 @@
*/
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <libyul/YulString.h>
#include <set>
-namespace dev
-{
namespace yul
{
@@ -58,4 +56,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/RedundantAssignEliminator.cpp b/libyul/optimiser/RedundantAssignEliminator.cpp
index b7217074..7b18e8ca 100644
--- a/libyul/optimiser/RedundantAssignEliminator.cpp
+++ b/libyul/optimiser/RedundantAssignEliminator.cpp
@@ -22,8 +22,7 @@
#include <libyul/optimiser/RedundantAssignEliminator.h>
#include <libyul/optimiser/Semantics.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/CommonData.h>
@@ -31,7 +30,7 @@
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
using namespace dev::solidity;
void RedundantAssignEliminator::operator()(Identifier const& _identifier)
diff --git a/libyul/optimiser/RedundantAssignEliminator.h b/libyul/optimiser/RedundantAssignEliminator.h
index 76106aae..54d65823 100644
--- a/libyul/optimiser/RedundantAssignEliminator.h
+++ b/libyul/optimiser/RedundantAssignEliminator.h
@@ -21,14 +21,11 @@
#pragma once
-#include <libyul/ASTDataForward.h>
-
+#include <libyul/AsmDataForward.h>
#include <libyul/optimiser/ASTWalker.h>
#include <map>
-namespace dev
-{
namespace yul
{
@@ -190,4 +187,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/Rematerialiser.cpp b/libyul/optimiser/Rematerialiser.cpp
index 38d50ef4..4180bfc3 100644
--- a/libyul/optimiser/Rematerialiser.cpp
+++ b/libyul/optimiser/Rematerialiser.cpp
@@ -23,12 +23,11 @@
#include <libyul/optimiser/Metrics.h>
#include <libyul/optimiser/ASTCopier.h>
#include <libyul/Exceptions.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
void Rematerialiser::visit(Expression& _e)
{
diff --git a/libyul/optimiser/Rematerialiser.h b/libyul/optimiser/Rematerialiser.h
index f82465eb..b3841519 100644
--- a/libyul/optimiser/Rematerialiser.h
+++ b/libyul/optimiser/Rematerialiser.h
@@ -22,8 +22,6 @@
#include <libyul/optimiser/DataFlowAnalyzer.h>
-namespace dev
-{
namespace yul
{
@@ -36,9 +34,8 @@ class Rematerialiser: public DataFlowAnalyzer
{
protected:
using ASTModifier::visit;
- virtual void visit(Expression& _e) override;
+ void visit(Expression& _e) override;
};
}
-}
diff --git a/libyul/optimiser/SSATransform.cpp b/libyul/optimiser/SSATransform.cpp
index f209ee7b..928c0859 100644
--- a/libyul/optimiser/SSATransform.cpp
+++ b/libyul/optimiser/SSATransform.cpp
@@ -23,15 +23,15 @@
#include <libyul/optimiser/NameCollector.h>
#include <libyul/optimiser/NameDispenser.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/CommonData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace langutil;
+using namespace yul;
using namespace dev::solidity;
void SSATransform::operator()(Identifier& _identifier)
diff --git a/libyul/optimiser/SSATransform.h b/libyul/optimiser/SSATransform.h
index bb642549..4cb62f23 100644
--- a/libyul/optimiser/SSATransform.h
+++ b/libyul/optimiser/SSATransform.h
@@ -20,14 +20,11 @@
*/
#pragma once
-#include <libyul/ASTDataForward.h>
-
+#include <libyul/AsmDataForward.h>
#include <libyul/optimiser/ASTWalker.h>
#include <vector>
-namespace dev
-{
namespace yul
{
@@ -95,4 +92,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/SSAValueTracker.cpp b/libyul/optimiser/SSAValueTracker.cpp
index 491117da..35b29b04 100644
--- a/libyul/optimiser/SSAValueTracker.cpp
+++ b/libyul/optimiser/SSAValueTracker.cpp
@@ -21,11 +21,11 @@
#include <libyul/optimiser/SSAValueTracker.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
void SSAValueTracker::operator()(Assignment const& _assignment)
{
diff --git a/libyul/optimiser/SSAValueTracker.h b/libyul/optimiser/SSAValueTracker.h
index d1539c86..e182e013 100644
--- a/libyul/optimiser/SSAValueTracker.h
+++ b/libyul/optimiser/SSAValueTracker.h
@@ -26,8 +26,6 @@
#include <map>
#include <set>
-namespace dev
-{
namespace yul
{
@@ -41,8 +39,8 @@ class SSAValueTracker: public ASTWalker
{
public:
using ASTWalker::operator();
- virtual void operator()(VariableDeclaration const& _varDecl) override;
- virtual void operator()(Assignment const& _assignment) override;
+ void operator()(VariableDeclaration const& _varDecl) override;
+ void operator()(Assignment const& _assignment) override;
std::map<YulString, Expression const*> const& values() const { return m_values; }
Expression const* value(YulString _name) const { return m_values.at(_name); }
@@ -54,4 +52,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/Semantics.cpp b/libyul/optimiser/Semantics.cpp
index 3c49016e..91bb2709 100644
--- a/libyul/optimiser/Semantics.cpp
+++ b/libyul/optimiser/Semantics.cpp
@@ -21,8 +21,7 @@
#include <libyul/optimiser/Semantics.h>
#include <libyul/Exceptions.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libevmasm/SemanticInformation.h>
@@ -30,7 +29,7 @@
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
MovableChecker::MovableChecker(Expression const& _expression)
{
diff --git a/libyul/optimiser/Semantics.h b/libyul/optimiser/Semantics.h
index 620a91cb..70c50806 100644
--- a/libyul/optimiser/Semantics.h
+++ b/libyul/optimiser/Semantics.h
@@ -24,8 +24,6 @@
#include <set>
-namespace dev
-{
namespace yul
{
@@ -38,12 +36,12 @@ public:
MovableChecker() = default;
explicit MovableChecker(Expression const& _expression);
- virtual void operator()(Identifier const& _identifier) override;
- virtual void operator()(FunctionalInstruction const& _functionalInstruction) override;
- virtual void operator()(FunctionCall const& _functionCall) override;
+ void operator()(Identifier const& _identifier) override;
+ void operator()(FunctionalInstruction const& _functionalInstruction) override;
+ void operator()(FunctionCall const& _functionCall) override;
/// Disallow visiting anything apart from Expressions (this throws).
- virtual void visit(Statement const&) override;
+ void visit(Statement const&) override;
using ASTWalker::visit;
bool movable() const { return m_movable; }
@@ -57,4 +55,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/SimplificationRules.cpp b/libyul/optimiser/SimplificationRules.cpp
index 5721042f..b3190fef 100644
--- a/libyul/optimiser/SimplificationRules.cpp
+++ b/libyul/optimiser/SimplificationRules.cpp
@@ -24,14 +24,14 @@
#include <libyul/optimiser/ASTCopier.h>
#include <libyul/optimiser/Semantics.h>
#include <libyul/optimiser/SyntacticalEquality.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libevmasm/RuleList.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace langutil;
+using namespace yul;
SimplificationRule<Pattern> const* SimplificationRules::findFirstMatch(
@@ -123,7 +123,7 @@ bool Pattern::matches(Expression const& _expr, map<YulString, Expression const*>
if (expr->type() != typeid(Literal))
return false;
Literal const& literal = boost::get<Literal>(*expr);
- if (literal.kind != assembly::LiteralKind::Number)
+ if (literal.kind != LiteralKind::Number)
return false;
if (m_data && *m_data != u256(literal.value.str()))
return false;
@@ -193,7 +193,7 @@ Expression Pattern::toExpression(SourceLocation const& _location) const
if (m_kind == PatternKind::Constant)
{
assertThrow(m_data, OptimizerException, "No match group and no constant value given.");
- return Literal{_location, assembly::LiteralKind::Number, YulString{formatNumber(*m_data)}, {}};
+ return Literal{_location, LiteralKind::Number, YulString{formatNumber(*m_data)}, {}};
}
else if (m_kind == PatternKind::Operation)
{
@@ -208,7 +208,7 @@ Expression Pattern::toExpression(SourceLocation const& _location) const
u256 Pattern::d() const
{
Literal const& literal = boost::get<Literal>(matchGroupValue());
- assertThrow(literal.kind == assembly::LiteralKind::Number, OptimizerException, "");
+ assertThrow(literal.kind == LiteralKind::Number, OptimizerException, "");
assertThrow(isValidDecimal(literal.value.str()) || isValidHex(literal.value.str()), OptimizerException, "");
return u256(literal.value.str());
}
diff --git a/libyul/optimiser/SimplificationRules.h b/libyul/optimiser/SimplificationRules.h
index b608ca91..16aaba04 100644
--- a/libyul/optimiser/SimplificationRules.h
+++ b/libyul/optimiser/SimplificationRules.h
@@ -23,17 +23,14 @@
#include <libevmasm/ExpressionClasses.h>
#include <libevmasm/SimplificationRule.h>
-#include <libyul/ASTDataForward.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmDataForward.h>
+#include <libyul/AsmData.h>
#include <boost/noncopyable.hpp>
#include <functional>
#include <vector>
-namespace dev
-{
namespace yul
{
@@ -86,11 +83,11 @@ public:
/// Matches any expression.
Pattern(PatternKind _kind = PatternKind::Any): m_kind(_kind) {}
// Matches a specific constant value.
- Pattern(unsigned _value): Pattern(u256(_value)) {}
+ Pattern(unsigned _value): Pattern(dev::u256(_value)) {}
// Matches a specific constant value.
- Pattern(u256 const& _value): m_kind(PatternKind::Constant), m_data(std::make_shared<u256>(_value)) {}
+ Pattern(dev::u256 const& _value): m_kind(PatternKind::Constant), m_data(std::make_shared<dev::u256>(_value)) {}
// Matches a given instruction with given arguments
- Pattern(solidity::Instruction _instruction, std::vector<Pattern> const& _arguments = {});
+ Pattern(dev::solidity::Instruction _instruction, std::vector<Pattern> const& _arguments = {});
/// Sets this pattern to be part of the match group with the identifier @a _group.
/// Inside one rule, all patterns in the same match group have to match expressions from the
/// same expression equivalence class.
@@ -101,24 +98,23 @@ public:
std::vector<Pattern> arguments() const { return m_arguments; }
/// @returns the data of the matched expression if this pattern is part of a match group.
- u256 d() const;
+ dev::u256 d() const;
- solidity::Instruction instruction() const;
+ dev::solidity::Instruction instruction() const;
/// Turns this pattern into an actual expression. Should only be called
/// for patterns resulting from an action, i.e. with match groups assigned.
- Expression toExpression(SourceLocation const& _location) const;
+ Expression toExpression(langutil::SourceLocation const& _location) const;
private:
Expression const& matchGroupValue() const;
PatternKind m_kind = PatternKind::Any;
- solidity::Instruction m_instruction; ///< Only valid if m_kind is Operation
- std::shared_ptr<u256> m_data; ///< Only valid if m_kind is Constant
+ dev::solidity::Instruction m_instruction; ///< Only valid if m_kind is Operation
+ std::shared_ptr<dev::u256> m_data; ///< Only valid if m_kind is Constant
std::vector<Pattern> m_arguments;
unsigned m_matchGroup = 0;
std::map<unsigned, Expression const*>* m_matchGroups = nullptr;
};
}
-}
diff --git a/libyul/optimiser/Substitution.cpp b/libyul/optimiser/Substitution.cpp
index 9b3d4c03..bc9efe96 100644
--- a/libyul/optimiser/Substitution.cpp
+++ b/libyul/optimiser/Substitution.cpp
@@ -20,11 +20,11 @@
#include <libyul/optimiser/Substitution.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
Expression Substitution::translate(Expression const& _expression)
{
diff --git a/libyul/optimiser/Substitution.h b/libyul/optimiser/Substitution.h
index 59ee4620..41f73b92 100644
--- a/libyul/optimiser/Substitution.h
+++ b/libyul/optimiser/Substitution.h
@@ -21,13 +21,10 @@
#pragma once
#include <libyul/optimiser/ASTCopier.h>
-
#include <libyul/YulString.h>
#include <map>
-namespace dev
-{
namespace yul
{
@@ -40,11 +37,10 @@ public:
Substitution(std::map<YulString, Expression const*> const& _substitutions):
m_substitutions(_substitutions)
{}
- virtual Expression translate(Expression const& _expression) override;
+ Expression translate(Expression const& _expression) override;
private:
std::map<YulString, Expression const*> const& m_substitutions;
};
}
-}
diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp
index 7d52a5a8..36f0e1eb 100644
--- a/libyul/optimiser/Suite.cpp
+++ b/libyul/optimiser/Suite.cpp
@@ -27,6 +27,7 @@
#include <libyul/optimiser/ExpressionJoiner.h>
#include <libyul/optimiser/ExpressionInliner.h>
#include <libyul/optimiser/FullInliner.h>
+#include <libyul/optimiser/ForLoopInitRewriter.h>
#include <libyul/optimiser/Rematerialiser.h>
#include <libyul/optimiser/UnusedPruner.h>
#include <libyul/optimiser/ExpressionSimplifier.h>
@@ -34,21 +35,19 @@
#include <libyul/optimiser/SSATransform.h>
#include <libyul/optimiser/RedundantAssignEliminator.h>
#include <libyul/optimiser/VarDeclPropagator.h>
-
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
-#include <libsolidity/inlineasm/AsmData.h>
-
-#include <libsolidity/inlineasm/AsmPrinter.h>
+#include <libyul/AsmAnalysisInfo.h>
+#include <libyul/AsmData.h>
+#include <libyul/AsmPrinter.h>
#include <libdevcore/CommonData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
void OptimiserSuite::run(
Block& _ast,
- solidity::assembly::AsmAnalysisInfo const& _analysisInfo,
+ AsmAnalysisInfo const& _analysisInfo,
set<YulString> const& _externallyUsedIdentifiers
)
{
@@ -58,6 +57,7 @@ void OptimiserSuite::run(
(FunctionHoister{})(ast);
(FunctionGrouper{})(ast);
+ (ForLoopInitRewriter{})(ast);
NameDispenser dispenser{ast};
diff --git a/libyul/optimiser/Suite.h b/libyul/optimiser/Suite.h
index 5b564c56..795326b4 100644
--- a/libyul/optimiser/Suite.h
+++ b/libyul/optimiser/Suite.h
@@ -20,23 +20,16 @@
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <libyul/YulString.h>
#include <set>
-namespace dev
-{
-namespace solidity
-{
-namespace assembly
-{
-struct AsmAnalysisInfo;
-}
-}
namespace yul
{
+struct AsmAnalysisInfo;
+
/**
* Optimiser suite that combines all steps and also provides the settings for the heuristics
*/
@@ -45,11 +38,10 @@ class OptimiserSuite
public:
static void run(
Block& _ast,
- solidity::assembly::AsmAnalysisInfo const& _analysisInfo,
+ AsmAnalysisInfo const& _analysisInfo,
std::set<YulString> const& _externallyUsedIdentifiers = {}
);
};
}
-}
diff --git a/libyul/optimiser/SyntacticalEquality.cpp b/libyul/optimiser/SyntacticalEquality.cpp
index 66912383..99ce06e5 100644
--- a/libyul/optimiser/SyntacticalEquality.cpp
+++ b/libyul/optimiser/SyntacticalEquality.cpp
@@ -21,14 +21,13 @@
#include <libyul/optimiser/SyntacticalEquality.h>
#include <libyul/Exceptions.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/CommonData.h>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
bool SyntacticalEqualityChecker::equal(Expression const& _e1, Expression const& _e2)
{
diff --git a/libyul/optimiser/SyntacticalEquality.h b/libyul/optimiser/SyntacticalEquality.h
index e9fbebe0..63c51b4f 100644
--- a/libyul/optimiser/SyntacticalEquality.h
+++ b/libyul/optimiser/SyntacticalEquality.h
@@ -20,12 +20,10 @@
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <vector>
-namespace dev
-{
namespace yul
{
@@ -47,4 +45,3 @@ protected:
};
}
-}
diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp
index 71e86798..31aead82 100644
--- a/libyul/optimiser/UnusedPruner.cpp
+++ b/libyul/optimiser/UnusedPruner.cpp
@@ -24,14 +24,13 @@
#include <libyul/optimiser/Semantics.h>
#include <libyul/optimiser/Utilities.h>
#include <libyul/Exceptions.h>
-
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <boost/algorithm/cxx11/none_of.hpp>
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
UnusedPruner::UnusedPruner(Block& _ast, set<YulString> const& _externallyUsedFunctions)
{
diff --git a/libyul/optimiser/UnusedPruner.h b/libyul/optimiser/UnusedPruner.h
index b5aea3dd..64e02b35 100644
--- a/libyul/optimiser/UnusedPruner.h
+++ b/libyul/optimiser/UnusedPruner.h
@@ -26,8 +26,6 @@
#include <map>
#include <set>
-namespace dev
-{
namespace yul
{
@@ -45,7 +43,7 @@ public:
explicit UnusedPruner(Block& _ast, std::set<YulString> const& _externallyUsedFunctions = {});
using ASTModifier::operator();
- virtual void operator()(Block& _block) override;
+ void operator()(Block& _block) override;
// @returns true iff the code changed in the previous run.
bool shouldRunAgain() const { return m_shouldRunAgain; }
@@ -62,4 +60,3 @@ private:
};
}
-}
diff --git a/libyul/optimiser/Utilities.cpp b/libyul/optimiser/Utilities.cpp
index df01ed39..b8cdd339 100644
--- a/libyul/optimiser/Utilities.cpp
+++ b/libyul/optimiser/Utilities.cpp
@@ -20,7 +20,7 @@
#include <libyul/optimiser/Utilities.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/CommonData.h>
@@ -28,9 +28,9 @@
using namespace std;
using namespace dev;
-using namespace dev::yul;
+using namespace yul;
-void dev::yul::removeEmptyBlocks(Block& _block)
+void yul::removeEmptyBlocks(Block& _block)
{
auto isEmptyBlock = [](Statement const& _st) -> bool {
return _st.type() == typeid(Block) && boost::get<Block>(_st).statements.empty();
diff --git a/libyul/optimiser/Utilities.h b/libyul/optimiser/Utilities.h
index 5b18a27c..c543b119 100644
--- a/libyul/optimiser/Utilities.h
+++ b/libyul/optimiser/Utilities.h
@@ -20,10 +20,8 @@
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
-namespace dev
-{
namespace yul
{
@@ -31,4 +29,3 @@ namespace yul
void removeEmptyBlocks(Block& _block);
}
-}
diff --git a/libyul/optimiser/VarDeclPropagator.cpp b/libyul/optimiser/VarDeclPropagator.cpp
index 537b7020..bf974f44 100644
--- a/libyul/optimiser/VarDeclPropagator.cpp
+++ b/libyul/optimiser/VarDeclPropagator.cpp
@@ -16,7 +16,7 @@
*/
#include <libyul/optimiser/VarDeclPropagator.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <libdevcore/CommonData.h>
#include <boost/range/algorithm_ext/erase.hpp>
#include <algorithm>
@@ -24,10 +24,7 @@
using namespace std;
using namespace dev;
-using namespace dev::yul;
-
-using dev::solidity::assembly::TypedName;
-using dev::solidity::assembly::TypedNameList;
+using namespace yul;
void VarDeclPropagator::operator()(Block& _block)
{
diff --git a/libyul/optimiser/VarDeclPropagator.h b/libyul/optimiser/VarDeclPropagator.h
index 4522d23a..1908c214 100644
--- a/libyul/optimiser/VarDeclPropagator.h
+++ b/libyul/optimiser/VarDeclPropagator.h
@@ -17,16 +17,14 @@
#pragma once
-#include <libyul/ASTDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <libyul/optimiser/ASTWalker.h>
#include <libyul/Exceptions.h>
-#include <libsolidity/inlineasm/AsmDataForward.h>
+#include <libyul/AsmDataForward.h>
#include <vector>
#include <set>
#include <map>
-namespace dev
-{
namespace yul
{
@@ -60,4 +58,3 @@ private:
};
}
-}
diff --git a/scripts/build_emscripten.sh b/scripts/build_emscripten.sh
index cddcd4f8..14c497ae 100755
--- a/scripts/build_emscripten.sh
+++ b/scripts/build_emscripten.sh
@@ -30,5 +30,5 @@ set -e
if [[ "$OSTYPE" != "darwin"* ]]; then
./scripts/travis-emscripten/install_deps.sh
- docker run -v $(pwd):/root/project -w /root/project trzeci/emscripten:sdk-tag-1.35.4-64bit ./scripts/travis-emscripten/build_emscripten.sh
+ docker run -v $(pwd):/root/project -w /root/project trzeci/emscripten:sdk-tag-1.37.21-64bit ./scripts/travis-emscripten/build_emscripten.sh
fi
diff --git a/scripts/bytecodecompare/storebytecode.sh b/scripts/bytecodecompare/storebytecode.sh
index ccf6e60e..4208d67f 100755
--- a/scripts/bytecodecompare/storebytecode.sh
+++ b/scripts/bytecodecompare/storebytecode.sh
@@ -58,7 +58,7 @@ for (var optimize of [false, true])
if (filename !== undefined)
{
var inputs = {}
- inputs[filename] = fs.readFileSync(filename).toString()
+ inputs[filename] = { content: fs.readFileSync(filename).toString() }
var input = {
language: 'Solidity',
sources: inputs,
@@ -68,16 +68,22 @@ for (var optimize of [false, true])
}
}
var result = JSON.parse(compiler.compile(JSON.stringify(input)))
- if (!('contracts' in result) || Object.keys(result['contracts']).length === 0)
+ if (
+ !('contracts' in result) ||
+ Object.keys(result['contracts']).length === 0 ||
+ !result['contracts'][filename] ||
+ Object.keys(result['contracts'][filename]).length === 0
+ )
{
+ // NOTE: do not exit here because this may be run on source which cannot be compiled
console.log(filename + ': ERROR')
}
else
{
- for (var contractName in result['contracts'])
+ for (var contractName in result['contracts'][filename])
{
- console.log(contractName + ' ' + result['contracts'][contractName].evm.bytecode.object)
- console.log(contractName + ' ' + result['contracts'][contractName].metadata)
+ console.log(filename + ':' + contractName + ' ' + result['contracts'][filename][contractName].evm.bytecode.object)
+ console.log(filename + ':' + contractName + ' ' + result['contracts'][filename][contractName].metadata)
}
}
}
diff --git a/scripts/travis-emscripten/build_emscripten.sh b/scripts/travis-emscripten/build_emscripten.sh
index f49ff5b2..32899903 100755
--- a/scripts/travis-emscripten/build_emscripten.sh
+++ b/scripts/travis-emscripten/build_emscripten.sh
@@ -56,18 +56,14 @@ else
echo 'NODE_JS=["nodejs", "--stack_size=8192"]' > ~/.emscripten
fi
-
# Boost
echo -en 'travis_fold:start:compiling_boost\\r'
-cd "$WORKSPACE"/boost_1_57_0
+cd "$WORKSPACE"/boost_1_67_0
# if b2 exists, it is a fresh checkout, otherwise it comes from the cache
# and is already compiled
test -e b2 && (
-sed -i 's|using gcc ;|using gcc : : em++ ;|g' ./project-config.jam
-sed -i 's|$(archiver\[1\])|emar|g' ./tools/build/src/tools/gcc.jam
-sed -i 's|$(ranlib\[1\])|emranlib|g' ./tools/build/src/tools/gcc.jam
-./b2 link=static variant=release threading=single runtime-link=static \
- system regex filesystem unit_test_framework program_options
+./b2 toolset=emscripten link=static variant=release threading=single runtime-link=static \
+ system regex filesystem unit_test_framework program_options cxxflags="-Wno-unused-local-typedef -Wno-variadic-macros -Wno-c99-extensions -Wno-all"
find . -name 'libboost*.a' -exec cp {} . \;
rm -rf b2 libs doc tools more bin.v2 status
)
@@ -89,17 +85,12 @@ cmake \
-DBoost_FOUND=1 \
-DBoost_USE_STATIC_LIBS=1 \
-DBoost_USE_STATIC_RUNTIME=1 \
- -DBoost_INCLUDE_DIR="$WORKSPACE"/boost_1_57_0/ \
- -DBoost_FILESYSTEM_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_filesystem.a \
- -DBoost_FILESYSTEM_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_filesystem.a \
- -DBoost_PROGRAM_OPTIONS_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_program_options.a \
- -DBoost_PROGRAM_OPTIONS_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_program_options.a \
- -DBoost_REGEX_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_regex.a \
- -DBoost_REGEX_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_regex.a \
- -DBoost_SYSTEM_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_system.a \
- -DBoost_SYSTEM_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_system.a \
- -DBoost_UNIT_TEST_FRAMEWORK_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_unit_test_framework.a \
- -DBoost_UNIT_TEST_FRAMEWORK_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_unit_test_framework.a \
+ -DBoost_INCLUDE_DIR="$WORKSPACE"/boost_1_67_0/ \
+ -DBoost_FILESYSTEM_LIBRARY_RELEASE="$WORKSPACE"/boost_1_67_0/libboost_filesystem.a \
+ -DBoost_PROGRAM_OPTIONS_LIBRARY_RELEASE="$WORKSPACE"/boost_1_67_0/libboost_program_options.a \
+ -DBoost_REGEX_LIBRARY_RELEASE="$WORKSPACE"/boost_1_67_0/libboost_regex.a \
+ -DBoost_SYSTEM_LIBRARY_RELEASE="$WORKSPACE"/boost_1_67_0/libboost_system.a \
+ -DBoost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE="$WORKSPACE"/boost_1_67_0/libboost_unit_test_framework.a \
-DTESTS=0 \
..
make -j 4
diff --git a/scripts/travis-emscripten/install_deps.sh b/scripts/travis-emscripten/install_deps.sh
index 45c16a9f..155506e4 100755
--- a/scripts/travis-emscripten/install_deps.sh
+++ b/scripts/travis-emscripten/install_deps.sh
@@ -30,11 +30,19 @@
set -ev
echo -en 'travis_fold:start:installing_dependencies\\r'
-test -e boost_1_57_0 -a -e boost_1_57_0/boost || (
-wget 'https://sourceforge.net/projects/boost/files/boost/1.57.0/boost_1_57_0.tar.gz/download'\
- -O - | tar xz
-cd boost_1_57_0
-./bootstrap.sh --with-toolset=gcc --with-libraries=thread,system,regex,date_time,chrono,filesystem,program_options,random
+test -e boost_1_67_0 -a -e boost_1_67_0/boost || (
+rm -rf boost_1_67_0
+rm -f boost.tar.xz
+wget -q 'https://sourceforge.net/projects/boost/files/boost/1.67.0/boost_1_67_0.tar.gz/download'\
+ -O boost.tar.xz
+test "$(shasum boost.tar.xz)" = "77e73c9fd7bf85b14067767b9e8fdc39b49ee0f2 boost.tar.xz"
+tar -xzf boost.tar.xz
+rm boost.tar.xz
+cd boost_1_67_0
+./bootstrap.sh
+wget -q 'https://raw.githubusercontent.com/tee3/boost-build-emscripten/master/emscripten.jam'
+test "$(shasum emscripten.jam)" = "a7e13fc2c1e53b0e079ef440622f879aa6da3049 emscripten.jam"
+echo "using emscripten : : em++ ;" >> project-config.jam
)
cd ..
echo -en 'travis_fold:end:installing_dependencies\\r'
diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp
index 844cef90..7f64d8ac 100644
--- a/solc/CommandLineInterface.cpp
+++ b/solc/CommandLineInterface.cpp
@@ -26,15 +26,15 @@
#include "license.h"
#include <libsolidity/interface/Version.h>
-#include <libsolidity/parsing/Scanner.h>
+#include <liblangutil/Scanner.h>
#include <libsolidity/parsing/Parser.h>
#include <libsolidity/ast/ASTPrinter.h>
#include <libsolidity/ast/ASTJsonConverter.h>
#include <libsolidity/analysis/NameAndTypeResolver.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <libsolidity/interface/CompilerStack.h>
#include <libsolidity/interface/StandardCompiler.h>
-#include <libsolidity/interface/SourceReferenceFormatter.h>
+#include <liblangutil/SourceReferenceFormatter.h>
#include <libsolidity/interface/GasEstimator.h>
#include <libsolidity/interface/AssemblyStack.h>
@@ -62,6 +62,7 @@
#include <fstream>
using namespace std;
+using namespace langutil;
namespace po = boost::program_options;
namespace dev
@@ -69,6 +70,24 @@ namespace dev
namespace solidity
{
+bool g_hasOutput = false;
+
+std::ostream& sout()
+{
+ g_hasOutput = true;
+ return cout;
+}
+
+std::ostream& serr(bool _used = true)
+{
+ if (_used)
+ g_hasOutput = true;
+ return cerr;
+}
+
+#define cout
+#define cerr
+
static string const g_stdinFileNameStr = "<stdin>";
static string const g_strAbi = "abi";
static string const g_strAllowPaths = "allow-paths";
@@ -180,7 +199,7 @@ static set<string> const g_machineArgs
static void version()
{
- cout <<
+ sout() <<
"solc, the solidity compiler commandline interface" <<
endl <<
"Version: " <<
@@ -191,9 +210,9 @@ static void version()
static void license()
{
- cout << otherLicenses << endl;
+ sout() << otherLicenses << endl;
// This is a static variable generated by cmake from LICENSE.txt
- cout << licenseText << endl;
+ sout() << licenseText << endl;
exit(0);
}
@@ -229,8 +248,8 @@ void CommandLineInterface::handleBinary(string const& _contract)
createFile(m_compiler->filesystemFriendlyName(_contract) + ".bin", objectWithLinkRefsHex(m_compiler->object(_contract)));
else
{
- cout << "Binary: " << endl;
- cout << objectWithLinkRefsHex(m_compiler->object(_contract)) << endl;
+ sout() << "Binary: " << endl;
+ sout() << objectWithLinkRefsHex(m_compiler->object(_contract)) << endl;
}
}
if (m_args.count(g_argBinaryRuntime))
@@ -239,8 +258,8 @@ void CommandLineInterface::handleBinary(string const& _contract)
createFile(m_compiler->filesystemFriendlyName(_contract) + ".bin-runtime", objectWithLinkRefsHex(m_compiler->runtimeObject(_contract)));
else
{
- cout << "Binary of the runtime part: " << endl;
- cout << objectWithLinkRefsHex(m_compiler->runtimeObject(_contract)) << endl;
+ sout() << "Binary of the runtime part: " << endl;
+ sout() << objectWithLinkRefsHex(m_compiler->runtimeObject(_contract)) << endl;
}
}
}
@@ -251,9 +270,9 @@ void CommandLineInterface::handleOpcode(string const& _contract)
createFile(m_compiler->filesystemFriendlyName(_contract) + ".opcode", solidity::disassemble(m_compiler->object(_contract).bytecode));
else
{
- cout << "Opcodes: " << endl;
- cout << solidity::disassemble(m_compiler->object(_contract).bytecode);
- cout << endl;
+ sout() << "Opcodes: " << endl;
+ sout() << solidity::disassemble(m_compiler->object(_contract).bytecode);
+ sout() << endl;
}
}
@@ -278,7 +297,7 @@ void CommandLineInterface::handleSignatureHashes(string const& _contract)
if (m_args.count(g_argOutputDir))
createFile(m_compiler->filesystemFriendlyName(_contract) + ".signatures", out);
else
- cout << "Function signatures: " << endl << out;
+ sout() << "Function signatures: " << endl << out;
}
void CommandLineInterface::handleMetadata(string const& _contract)
@@ -290,7 +309,7 @@ void CommandLineInterface::handleMetadata(string const& _contract)
if (m_args.count(g_argOutputDir))
createFile(m_compiler->filesystemFriendlyName(_contract) + "_meta.json", data);
else
- cout << "Metadata: " << endl << data << endl;
+ sout() << "Metadata: " << endl << data << endl;
}
void CommandLineInterface::handleABI(string const& _contract)
@@ -302,7 +321,7 @@ void CommandLineInterface::handleABI(string const& _contract)
if (m_args.count(g_argOutputDir))
createFile(m_compiler->filesystemFriendlyName(_contract) + ".abi", data);
else
- cout << "Contract JSON ABI " << endl << data << endl;
+ sout() << "Contract JSON ABI " << endl << data << endl;
}
void CommandLineInterface::handleNatspec(bool _natspecDev, string const& _contract)
@@ -336,8 +355,8 @@ void CommandLineInterface::handleNatspec(bool _natspecDev, string const& _contra
createFile(m_compiler->filesystemFriendlyName(_contract) + suffix, output);
else
{
- cout << title << endl;
- cout << output << endl;
+ sout() << title << endl;
+ sout() << output << endl;
}
}
@@ -346,39 +365,39 @@ void CommandLineInterface::handleNatspec(bool _natspecDev, string const& _contra
void CommandLineInterface::handleGasEstimation(string const& _contract)
{
Json::Value estimates = m_compiler->gasEstimates(_contract);
- cout << "Gas estimation:" << endl;
+ sout() << "Gas estimation:" << endl;
if (estimates["creation"].isObject())
{
Json::Value creation = estimates["creation"];
- cout << "construction:" << endl;
- cout << " " << creation["executionCost"].asString();
- cout << " + " << creation["codeDepositCost"].asString();
- cout << " = " << creation["totalCost"].asString() << endl;
+ sout() << "construction:" << endl;
+ sout() << " " << creation["executionCost"].asString();
+ sout() << " + " << creation["codeDepositCost"].asString();
+ sout() << " = " << creation["totalCost"].asString() << endl;
}
if (estimates["external"].isObject())
{
Json::Value externalFunctions = estimates["external"];
- cout << "external:" << endl;
+ sout() << "external:" << endl;
for (auto const& name: externalFunctions.getMemberNames())
{
if (name.empty())
- cout << " fallback:\t";
+ sout() << " fallback:\t";
else
- cout << " " << name << ":\t";
- cout << externalFunctions[name].asString() << endl;
+ sout() << " " << name << ":\t";
+ sout() << externalFunctions[name].asString() << endl;
}
}
if (estimates["internal"].isObject())
{
Json::Value internalFunctions = estimates["internal"];
- cout << "internal:" << endl;
+ sout() << "internal:" << endl;
for (auto const& name: internalFunctions.getMemberNames())
{
- cout << " " << name << ":\t";
- cout << internalFunctions[name].asString() << endl;
+ sout() << " " << name << ":\t";
+ sout() << internalFunctions[name].asString() << endl;
}
}
}
@@ -400,7 +419,7 @@ bool CommandLineInterface::readInputFilesAndConfigureRemappings()
}
else
{
- cerr << "Invalid remapping: \"" << path << "\"." << endl;
+ serr() << "Invalid remapping: \"" << path << "\"." << endl;
return false;
}
}
@@ -413,11 +432,11 @@ bool CommandLineInterface::readInputFilesAndConfigureRemappings()
{
if (!ignoreMissing)
{
- cerr << infile << " is not found." << endl;
+ serr() << infile << " is not found." << endl;
return false;
}
else
- cerr << infile << " is not found. Skipping." << endl;
+ serr() << infile << " is not found. Skipping." << endl;
continue;
}
@@ -426,11 +445,11 @@ bool CommandLineInterface::readInputFilesAndConfigureRemappings()
{
if (!ignoreMissing)
{
- cerr << infile << " is not a valid file." << endl;
+ serr() << infile << " is not a valid file." << endl;
return false;
}
else
- cerr << infile << " is not a valid file. Skipping." << endl;
+ serr() << infile << " is not a valid file. Skipping." << endl;
continue;
}
@@ -444,7 +463,7 @@ bool CommandLineInterface::readInputFilesAndConfigureRemappings()
m_sourceCodes[g_stdinFileName] = dev::readStandardInput();
if (m_sourceCodes.size() == 0)
{
- cerr << "No input files given. If you wish to use the standard input please specify \"-\" explicitly." << endl;
+ serr() << "No input files given. If you wish to use the standard input please specify \"-\" explicitly." << endl;
return false;
}
@@ -475,7 +494,7 @@ bool CommandLineInterface::parseLibraryOption(string const& _input)
auto colon = lib.rfind(':');
if (colon == string::npos)
{
- cerr << "Colon separator missing in library address specifier \"" << lib << "\"" << endl;
+ serr() << "Colon separator missing in library address specifier \"" << lib << "\"" << endl;
return false;
}
string libName(lib.begin(), lib.begin() + colon);
@@ -486,26 +505,26 @@ bool CommandLineInterface::parseLibraryOption(string const& _input)
addrString = addrString.substr(2);
if (addrString.empty())
{
- cerr << "Empty address provided for library \"" << libName << "\": " << endl;
- cerr << "Note that there should not be any whitespace after the colon." << endl;
+ serr() << "Empty address provided for library \"" << libName << "\": " << endl;
+ serr() << "Note that there should not be any whitespace after the colon." << endl;
return false;
}
else if (addrString.length() != 40)
{
- cerr << "Invalid length for address for library \"" << libName << "\": " << addrString.length() << " instead of 40 characters." << endl;
+ serr() << "Invalid length for address for library \"" << libName << "\": " << addrString.length() << " instead of 40 characters." << endl;
return false;
}
if (!passesAddressChecksum(addrString, false))
{
- cerr << "Invalid checksum on address for library \"" << libName << "\": " << addrString << endl;
- cerr << "The correct checksum is " << dev::getChecksummedAddress(addrString) << endl;
+ serr() << "Invalid checksum on address for library \"" << libName << "\": " << addrString << endl;
+ serr() << "The correct checksum is " << dev::getChecksummedAddress(addrString) << endl;
return false;
}
bytes binAddr = fromHex(addrString);
h160 address(binAddr, h160::AlignRight);
if (binAddr.size() > 20 || address == h160())
{
- cerr << "Invalid address for library \"" << libName << "\": " << addrString << endl;
+ serr() << "Invalid address for library \"" << libName << "\": " << addrString << endl;
return false;
}
m_libraries[libName] = address;
@@ -525,7 +544,7 @@ void CommandLineInterface::createFile(string const& _fileName, string const& _da
string pathName = (p / _fileName).string();
if (fs::exists(pathName) && !m_args.count(g_strOverwrite))
{
- cerr << "Refusing to overwrite existing file \"" << pathName << "\" (use --overwrite to force)." << endl;
+ serr() << "Refusing to overwrite existing file \"" << pathName << "\" (use --overwrite to force)." << endl;
m_error = true;
return;
}
@@ -542,6 +561,8 @@ void CommandLineInterface::createJson(string const& _fileName, string const& _js
bool CommandLineInterface::parseArguments(int _argc, char** _argv)
{
+ g_hasOutput = false;
+
// Declare the supported options.
po::options_description desc(R"(solc, the Solidity commandline compiler.
@@ -666,13 +687,13 @@ Allowed options)",
}
catch (po::error const& _exception)
{
- cerr << _exception.what() << endl;
+ serr() << _exception.what() << endl;
return false;
}
if (m_args.count(g_argHelp) || (isatty(fileno(stdin)) && _argc == 1))
{
- cout << desc;
+ sout() << desc;
return false;
}
@@ -694,7 +715,7 @@ Allowed options)",
for (string const& item: boost::split(requests, m_args[g_argCombinedJson].as<string>(), boost::is_any_of(",")))
if (!g_combinedJsonArgs.count(item))
{
- cerr << "Invalid option to --combined-json: " << item << endl;
+ serr() << "Invalid option to --combined-json: " << item << endl;
return false;
}
}
@@ -758,9 +779,7 @@ bool CommandLineInterface::processInput()
// path comparison in later parts of the code, so we need to strip
// it.
if (filesystem_path.filename() == ".")
- {
filesystem_path.remove_filename();
- }
m_allowedDirectories.push_back(filesystem_path);
}
}
@@ -769,7 +788,7 @@ bool CommandLineInterface::processInput()
{
string input = dev::readStandardInput();
StandardCompiler compiler(fileReader);
- cout << compiler.compile(input) << endl;
+ sout() << compiler.compile(input) << endl;
return true;
}
@@ -787,7 +806,7 @@ bool CommandLineInterface::processInput()
boost::optional<EVMVersion> versionOption = EVMVersion::fromString(versionOptionStr);
if (!versionOption)
{
- cerr << "Invalid option for --evm-version: " << versionOptionStr << endl;
+ serr() << "Invalid option for --evm-version: " << versionOptionStr << endl;
return false;
}
m_evmVersion = *versionOption;
@@ -812,7 +831,7 @@ bool CommandLineInterface::processInput()
targetMachine = Machine::eWasm;
else
{
- cerr << "Invalid option for --machine: " << machine << endl;
+ serr() << "Invalid option for --machine: " << machine << endl;
return false;
}
}
@@ -827,8 +846,8 @@ bool CommandLineInterface::processInput()
m_compiler.reset(new CompilerStack(fileReader));
- auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compiler->scanner(_sourceName); };
- SourceReferenceFormatter formatter(cerr, scannerFromSourceName);
+ auto scannerFromSourceName = [&](string const& _sourceName) -> Scanner const& { return m_compiler->scanner(_sourceName); };
+ SourceReferenceFormatter formatter(serr(false), scannerFromSourceName);
try
{
@@ -849,48 +868,55 @@ bool CommandLineInterface::processInput()
bool successful = m_compiler->compile();
for (auto const& error: m_compiler->errors())
+ {
+ g_hasOutput = true;
formatter.printExceptionInformation(
*error,
(error->type() == Error::Type::Warning) ? "Warning" : "Error"
);
+ }
if (!successful)
return false;
}
catch (CompilerError const& _exception)
{
+ g_hasOutput = true;
formatter.printExceptionInformation(_exception, "Compiler error");
return false;
}
catch (InternalCompilerError const& _exception)
{
- cerr << "Internal compiler error during compilation:" << endl
+ serr() << "Internal compiler error during compilation:" << endl
<< boost::diagnostic_information(_exception);
return false;
}
catch (UnimplementedFeatureError const& _exception)
{
- cerr << "Unimplemented feature:" << endl
+ serr() << "Unimplemented feature:" << endl
<< boost::diagnostic_information(_exception);
return false;
}
catch (Error const& _error)
{
if (_error.type() == Error::Type::DocstringParsingError)
- cerr << "Documentation parsing error: " << *boost::get_error_info<errinfo_comment>(_error) << endl;
+ serr() << "Documentation parsing error: " << *boost::get_error_info<errinfo_comment>(_error) << endl;
else
+ {
+ g_hasOutput = true;
formatter.printExceptionInformation(_error, _error.typeName());
+ }
return false;
}
catch (Exception const& _exception)
{
- cerr << "Exception during compilation: " << boost::diagnostic_information(_exception) << endl;
+ serr() << "Exception during compilation: " << boost::diagnostic_information(_exception) << endl;
return false;
}
catch (...)
{
- cerr << "Unknown exception during compilation." << endl;
+ serr() << "Unknown exception during compilation." << endl;
return false;
}
@@ -971,7 +997,7 @@ void CommandLineInterface::handleCombinedJSON()
if (m_args.count(g_argOutputDir))
createJson("combined", json);
else
- cout << json << endl;
+ sout() << json << endl;
}
void CommandLineInterface::handleAst(string const& _argStr)
@@ -1027,10 +1053,10 @@ void CommandLineInterface::handleAst(string const& _argStr)
}
else
{
- cout << title << endl << endl;
+ sout() << title << endl << endl;
for (auto const& sourceCode: m_sourceCodes)
{
- cout << endl << "======= " << sourceCode.first << " =======" << endl;
+ sout() << endl << "======= " << sourceCode.first << " =======" << endl;
if (_argStr == g_argAst)
{
ASTPrinter printer(
@@ -1038,10 +1064,10 @@ void CommandLineInterface::handleAst(string const& _argStr)
sourceCode.second,
gasCosts
);
- printer.print(cout);
+ printer.print(sout());
}
else
- ASTJsonConverter(legacyFormat, m_compiler->sourceIndices()).print(cout, m_compiler->ast(sourceCode.first));
+ ASTJsonConverter(legacyFormat, m_compiler->sourceIndices()).print(sout(), m_compiler->ast(sourceCode.first));
}
}
}
@@ -1089,7 +1115,7 @@ bool CommandLineInterface::link()
if (it == end) break;
if (end - it < placeholderSize)
{
- cerr << "Error in binary object file " << src.first << " at position " << (end - src.second.begin()) << endl;
+ serr() << "Error in binary object file " << src.first << " at position " << (end - src.second.begin()) << endl;
return false;
}
@@ -1100,7 +1126,7 @@ bool CommandLineInterface::link()
copy(hexStr.begin(), hexStr.end(), it);
}
else
- cerr << "Reference \"" << name << "\" in file \"" << src.first << "\" still unresolved." << endl;
+ serr() << "Reference \"" << name << "\" in file \"" << src.first << "\" still unresolved." << endl;
it += placeholderSize;
}
// Remove hints for resolved libraries.
@@ -1116,17 +1142,18 @@ void CommandLineInterface::writeLinkedFiles()
{
for (auto const& src: m_sourceCodes)
if (src.first == g_stdinFileName)
- cout << src.second << endl;
+ sout() << src.second << endl;
else
{
ofstream outFile(src.first);
outFile << src.second;
if (!outFile)
{
- cerr << "Could not write to file " << src.first << ". Aborting." << endl;
+ serr() << "Could not write to file " << src.first << ". Aborting." << endl;
return;
}
}
+ sout() << "Linking completed." << endl;
}
string CommandLineInterface::libraryPlaceholderHint(string const& _libraryName)
@@ -1163,12 +1190,12 @@ bool CommandLineInterface::assemble(
}
catch (Exception const& _exception)
{
- cerr << "Exception in assembler: " << boost::diagnostic_information(_exception) << endl;
+ serr() << "Exception in assembler: " << boost::diagnostic_information(_exception) << endl;
return false;
}
catch (...)
{
- cerr << "Unknown exception in assembler." << endl;
+ serr() << "Unknown exception in assembler." << endl;
return false;
}
}
@@ -1177,13 +1204,16 @@ bool CommandLineInterface::assemble(
{
auto const& stack = sourceAndStack.second;
auto scannerFromSourceName = [&](string const&) -> Scanner const& { return stack.scanner(); };
- SourceReferenceFormatter formatter(cerr, scannerFromSourceName);
+ SourceReferenceFormatter formatter(serr(false), scannerFromSourceName);
for (auto const& error: stack.errors())
+ {
+ g_hasOutput = true;
formatter.printExceptionInformation(
*error,
(error->type() == Error::Type::Warning) ? "Warning" : "Error"
);
+ }
if (!Error::containsOnlyWarnings(stack.errors()))
successful = false;
}
@@ -1197,11 +1227,11 @@ bool CommandLineInterface::assemble(
_targetMachine == AssemblyStack::Machine::EVM ? "EVM" :
_targetMachine == AssemblyStack::Machine::EVM15 ? "EVM 1.5" :
"eWasm";
- cout << endl << "======= " << src.first << " (" << machine << ") =======" << endl;
+ sout() << endl << "======= " << src.first << " (" << machine << ") =======" << endl;
AssemblyStack& stack = assemblyStacks[src.first];
- cout << endl << "Pretty printed source:" << endl;
- cout << stack.print() << endl;
+ sout() << endl << "Pretty printed source:" << endl;
+ sout() << stack.print() << endl;
MachineAssemblyObject object;
try
@@ -1210,26 +1240,26 @@ bool CommandLineInterface::assemble(
}
catch (Exception const& _exception)
{
- cerr << "Exception while assembling: " << boost::diagnostic_information(_exception) << endl;
+ serr() << "Exception while assembling: " << boost::diagnostic_information(_exception) << endl;
return false;
}
catch (...)
{
- cerr << "Unknown exception while assembling." << endl;
+ serr() << "Unknown exception while assembling." << endl;
return false;
}
- cout << endl << "Binary representation:" << endl;
+ sout() << endl << "Binary representation:" << endl;
if (object.bytecode)
- cout << object.bytecode->toHex() << endl;
+ sout() << object.bytecode->toHex() << endl;
else
- cerr << "No binary representation found." << endl;
+ serr() << "No binary representation found." << endl;
- cout << endl << "Text representation:" << endl;
+ sout() << endl << "Text representation:" << endl;
if (!object.assembly.empty())
- cout << object.assembly << endl;
+ sout() << object.assembly << endl;
else
- cerr << "No text representation found." << endl;
+ serr() << "No text representation found." << endl;
}
return true;
@@ -1248,7 +1278,7 @@ void CommandLineInterface::outputCompilationResults()
for (string const& contract: contracts)
{
if (needsHumanTargetedStdout(m_args))
- cout << endl << "======= " << contract << " =======" << endl;
+ sout() << endl << "======= " << contract << " =======" << endl;
// do we need EVM assembly?
if (m_args.count(g_argAsm) || m_args.count(g_argAsmJson))
@@ -1265,7 +1295,7 @@ void CommandLineInterface::outputCompilationResults()
}
else
{
- cout << "EVM assembly:" << endl << ret << endl;
+ sout() << "EVM assembly:" << endl << ret << endl;
}
}
@@ -1279,6 +1309,14 @@ void CommandLineInterface::outputCompilationResults()
handleNatspec(true, contract);
handleNatspec(false, contract);
} // end of contracts iteration
+
+ if (!g_hasOutput)
+ {
+ if (m_args.count(g_argOutputDir))
+ sout() << "Compiler run successful. Artifact(s) can be found in directory " << m_args.at(g_argOutputDir).as<string>() << "." << endl;
+ else
+ serr() << "Compiler run successful, no output requested." << endl;
+ }
}
}
diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h
index aa49383a..8dc00370 100644
--- a/solc/CommandLineInterface.h
+++ b/solc/CommandLineInterface.h
@@ -23,7 +23,7 @@
#include <libsolidity/interface/CompilerStack.h>
#include <libsolidity/interface/AssemblyStack.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <boost/program_options.hpp>
#include <boost/filesystem/path.hpp>
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 3b674502..10b78bdc 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -5,6 +5,8 @@ file(GLOB contracts_sources "contracts/*.cpp")
file(GLOB contracts_headers "contracts/*.h")
file(GLOB libdevcore_sources "libdevcore/*.cpp")
file(GLOB libdevcore_headers "libdevcore/*.h")
+file(GLOB liblangutil_sources "liblangutil/*.cpp")
+file(GLOB liblangutil_headers "liblangutil/*.h")
file(GLOB libevmasm_sources "libevmasm/*.cpp")
file(GLOB libevmasm_headers "libevmasm/*.h")
file(GLOB libyul_sources "libyul/*.cpp")
@@ -19,12 +21,13 @@ file(GLOB libsolidity_headers "libsolidity/*.h")
add_executable(soltest ${sources} ${headers}
${contracts_sources} ${contracts_headers}
${libdevcore_sources} ${libdevcore_headers}
+ ${liblangutil_sources} ${liblangutil_headers}
${libevmasm_sources} ${libevmasm_headers}
${libyul_sources} ${libyul_headers}
${liblll_sources} ${liblll_headers}
${libsolidity_sources} ${libsolidity_headers}
)
-target_link_libraries(soltest PRIVATE libsolc solidity evmasm devcore ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
+target_link_libraries(soltest PRIVATE libsolc yul solidity evmasm devcore ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
if (LLL)
target_link_libraries(soltest PRIVATE lll)
diff --git a/test/ExecutionFramework.h b/test/ExecutionFramework.h
index d6de95a3..86c1bcca 100644
--- a/test/ExecutionFramework.h
+++ b/test/ExecutionFramework.h
@@ -25,7 +25,7 @@
#include <test/Options.h>
#include <test/RPCSession.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <libdevcore/FixedHash.h>
#include <libdevcore/Keccak256.h>
diff --git a/test/Options.cpp b/test/Options.cpp
index da08eb37..9f0d6752 100644
--- a/test/Options.cpp
+++ b/test/Options.cpp
@@ -23,8 +23,8 @@
#include <test/Common.h>
-#include <libsolidity/interface/EVMVersion.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/EVMVersion.h>
+#include <liblangutil/Exceptions.h>
#include <boost/test/framework.hpp>
#include <boost/filesystem.hpp>
diff --git a/test/Options.h b/test/Options.h
index 0e8a51da..af6f06ee 100644
--- a/test/Options.h
+++ b/test/Options.h
@@ -19,7 +19,7 @@
#pragma once
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>
diff --git a/test/RPCSession.cpp b/test/RPCSession.cpp
index 9ac24972..0aae21a7 100644
--- a/test/RPCSession.cpp
+++ b/test/RPCSession.cpp
@@ -23,7 +23,7 @@
#include <test/Options.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/EVMVersion.h>
#include <libdevcore/CommonData.h>
diff --git a/test/libsolidity/TestCase.cpp b/test/TestCase.cpp
index 17972269..e9e2c9f2 100644
--- a/test/libsolidity/TestCase.cpp
+++ b/test/TestCase.cpp
@@ -15,7 +15,7 @@
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <test/libsolidity/TestCase.h>
+#include <test/TestCase.h>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
diff --git a/test/libsolidity/TestCase.h b/test/TestCase.h
index 3c05ae4e..3c05ae4e 100644
--- a/test/libsolidity/TestCase.h
+++ b/test/TestCase.h
diff --git a/test/boostTest.cpp b/test/boostTest.cpp
index 5352ef85..7cb0c143 100644
--- a/test/boostTest.cpp
+++ b/test/boostTest.cpp
@@ -38,6 +38,7 @@
#include <test/Options.h>
#include <test/libsolidity/ASTJSONTest.h>
#include <test/libsolidity/SyntaxTest.h>
+#include <test/libsolidity/SMTCheckerJSONTest.h>
#include <test/libyul/YulOptimizerTest.h>
#include <boost/algorithm/string.hpp>
@@ -143,15 +144,24 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
master,
dev::test::Options::get().testPath / "libyul",
"yulOptimizerTests",
- dev::yul::test::YulOptimizerTest::create
+ yul::test::YulOptimizerTest::create
) > 0, "no Yul Optimizer tests found");
if (!dev::test::Options::get().disableSMT)
+ {
solAssert(registerTests(
master,
dev::test::Options::get().testPath / "libsolidity",
"smtCheckerTests",
SyntaxTest::create
) > 0, "no SMT checker tests found");
+
+ solAssert(registerTests(
+ master,
+ dev::test::Options::get().testPath / "libsolidity",
+ "smtCheckerTestsJSON",
+ SMTCheckerTest::create
+ ) > 0, "no SMT checker JSON tests found");
+ }
if (dev::test::Options::get().disableIPC)
{
for (auto suite: {
diff --git a/test/contracts/AuctionRegistrar.cpp b/test/contracts/AuctionRegistrar.cpp
index eb274c09..6ce61a6e 100644
--- a/test/contracts/AuctionRegistrar.cpp
+++ b/test/contracts/AuctionRegistrar.cpp
@@ -112,7 +112,7 @@ contract GlobalRegistrar is Registrar, AuctionSystem {
uint constant c_renewalInterval = 365 days;
uint constant c_freeBytes = 12;
- function Registrar() public {
+ constructor() public {
// TODO: Populate with hall-of-fame.
}
diff --git a/test/libevmasm/Assembler.cpp b/test/libevmasm/Assembler.cpp
index 1c041596..5ad01594 100644
--- a/test/libevmasm/Assembler.cpp
+++ b/test/libevmasm/Assembler.cpp
@@ -30,6 +30,7 @@
#include <memory>
using namespace std;
+using namespace langutil;
using namespace dev::eth;
namespace dev
diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp
index c01e8758..c061b783 100644
--- a/test/libevmasm/Optimiser.cpp
+++ b/test/libevmasm/Optimiser.cpp
@@ -36,6 +36,7 @@
#include <memory>
using namespace std;
+using namespace langutil;
using namespace dev::eth;
namespace dev
diff --git a/test/libevmasm/SourceLocation.cpp b/test/liblangutil/SourceLocation.cpp
index 764da3cd..ac7a2173 100644
--- a/test/libevmasm/SourceLocation.cpp
+++ b/test/liblangutil/SourceLocation.cpp
@@ -20,13 +20,11 @@
* Unit tests for the SourceLocation class.
*/
-#include <libevmasm/SourceLocation.h>
+#include <liblangutil/SourceLocation.h>
#include <test/Options.h>
-namespace dev
-{
-namespace solidity
+namespace langutil
{
namespace test
{
@@ -46,5 +44,4 @@ BOOST_AUTO_TEST_CASE(test_fail)
BOOST_AUTO_TEST_SUITE_END()
}
-}
} // end namespaces
diff --git a/test/liblll/EndToEndTest.cpp b/test/liblll/EndToEndTest.cpp
index 60aef7b0..aad89b91 100644
--- a/test/liblll/EndToEndTest.cpp
+++ b/test/liblll/EndToEndTest.cpp
@@ -109,6 +109,19 @@ BOOST_AUTO_TEST_CASE(variables)
BOOST_CHECK(callFallback() == encodeArgs(u256(488)));
}
+BOOST_AUTO_TEST_CASE(with)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (set 'x 11)
+ (with 'y 22 { [0]:(+ (get 'x) (get 'y)) })
+ (return 0 32)))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callFallback() == toBigEndian(u256(33)));
+}
+
BOOST_AUTO_TEST_CASE(when)
{
char const* sourceCode = R"(
diff --git a/test/libsolidity/ABIDecoderTests.cpp b/test/libsolidity/ABIDecoderTests.cpp
index 94319985..291ed15a 100644
--- a/test/libsolidity/ABIDecoderTests.cpp
+++ b/test/libsolidity/ABIDecoderTests.cpp
@@ -22,7 +22,7 @@
#include <string>
#include <tuple>
#include <boost/test/unit_test.hpp>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <test/libsolidity/SolidityExecutionFramework.h>
#include <test/libsolidity/ABITestsCommon.h>
diff --git a/test/libsolidity/ABIEncoderTests.cpp b/test/libsolidity/ABIEncoderTests.cpp
index d2125cc7..b6e6cedd 100644
--- a/test/libsolidity/ABIEncoderTests.cpp
+++ b/test/libsolidity/ABIEncoderTests.cpp
@@ -22,7 +22,7 @@
#include <string>
#include <tuple>
#include <boost/test/unit_test.hpp>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <test/libsolidity/SolidityExecutionFramework.h>
#include <test/libsolidity/ABITestsCommon.h>
diff --git a/test/libsolidity/ASTJSONTest.h b/test/libsolidity/ASTJSONTest.h
index 6f24bb60..dcdaf221 100644
--- a/test/libsolidity/ASTJSONTest.h
+++ b/test/libsolidity/ASTJSONTest.h
@@ -18,7 +18,7 @@
#pragma once
#include <test/libsolidity/FormattedScope.h>
-#include <test/libsolidity/TestCase.h>
+#include <test/TestCase.h>
#include <iosfwd>
#include <string>
@@ -39,10 +39,10 @@ public:
{ return std::unique_ptr<TestCase>(new ASTJSONTest(_filename)); }
ASTJSONTest(std::string const& _filename);
- virtual bool run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
+ bool run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
- virtual void printSource(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) const override;
- virtual void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
+ void printSource(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) const override;
+ void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
private:
std::vector<std::pair<std::string, std::string>> m_sources;
std::string m_expectation;
diff --git a/test/libsolidity/AnalysisFramework.cpp b/test/libsolidity/AnalysisFramework.cpp
index ec98026c..bd24115c 100644
--- a/test/libsolidity/AnalysisFramework.cpp
+++ b/test/libsolidity/AnalysisFramework.cpp
@@ -23,11 +23,11 @@
#include <test/Options.h>
#include <libsolidity/interface/CompilerStack.h>
-#include <libsolidity/interface/SourceReferenceFormatter.h>
+#include <liblangutil/SourceReferenceFormatter.h>
#include <libsolidity/ast/AST.h>
-#include <libsolidity/parsing/Scanner.h>
+#include <liblangutil/Scanner.h>
#include <libdevcore/Keccak256.h>
@@ -35,6 +35,7 @@
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
using namespace dev::solidity::test;
@@ -127,7 +128,7 @@ string AnalysisFramework::formatError(Error const& _error) const
return SourceReferenceFormatter::formatExceptionInformation(
_error,
(_error.type() == Error::Type::Warning) ? "Warning" : "Error",
- [&](std::string const& _sourceName) -> solidity::Scanner const& { return m_compiler.scanner(_sourceName); }
+ [&](std::string const& _sourceName) -> Scanner const& { return m_compiler.scanner(_sourceName); }
);
}
diff --git a/test/libsolidity/AnalysisFramework.h b/test/libsolidity/AnalysisFramework.h
index a904617d..391a21da 100644
--- a/test/libsolidity/AnalysisFramework.h
+++ b/test/libsolidity/AnalysisFramework.h
@@ -45,7 +45,7 @@ class AnalysisFramework
{
protected:
- virtual std::pair<SourceUnit const*, ErrorList>
+ virtual std::pair<SourceUnit const*, langutil::ErrorList>
parseAnalyseAndReturnError(
std::string const& _source,
bool _reportWarnings = false,
@@ -56,10 +56,10 @@ protected:
SourceUnit const* parseAndAnalyse(std::string const& _source);
bool success(std::string const& _source);
- ErrorList expectError(std::string const& _source, bool _warning = false, bool _allowMultiple = false);
+ langutil::ErrorList expectError(std::string const& _source, bool _warning = false, bool _allowMultiple = false);
std::string formatErrors() const;
- std::string formatError(Error const& _error) const;
+ std::string formatError(langutil::Error const& _error) const;
static ContractDefinition const* retrieveContractByName(SourceUnit const& _source, std::string const& _name);
static FunctionTypePointer retrieveFunctionBySignature(
@@ -68,7 +68,7 @@ protected:
);
// filter out the warnings in m_warningsToFilter or all warnings if _includeWarnings is false
- ErrorList filterErrors(ErrorList const& _errorList, bool _includeWarnings) const;
+ langutil::ErrorList filterErrors(langutil::ErrorList const& _errorList, bool _includeWarnings) const;
std::vector<std::string> m_warningsToFilter = {"This is a pre-release compiler version"};
dev::solidity::CompilerStack m_compiler;
diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp
index 5e157678..926e29fe 100644
--- a/test/libsolidity/Assembly.cpp
+++ b/test/libsolidity/Assembly.cpp
@@ -22,16 +22,16 @@
#include <test/Options.h>
-#include <libevmasm/SourceLocation.h>
+#include <liblangutil/SourceLocation.h>
#include <libevmasm/Assembly.h>
-#include <libsolidity/parsing/Scanner.h>
+#include <liblangutil/Scanner.h>
#include <libsolidity/parsing/Parser.h>
#include <libsolidity/analysis/NameAndTypeResolver.h>
#include <libsolidity/codegen/Compiler.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/analysis/TypeChecker.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
#include <boost/test/unit_test.hpp>
@@ -39,6 +39,7 @@
#include <iostream>
using namespace std;
+using namespace langutil;
using namespace dev::eth;
namespace dev
diff --git a/test/libsolidity/ErrorCheck.cpp b/test/libsolidity/ErrorCheck.cpp
index fba2c897..e1f48fb2 100644
--- a/test/libsolidity/ErrorCheck.cpp
+++ b/test/libsolidity/ErrorCheck.cpp
@@ -27,6 +27,7 @@
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
namespace
diff --git a/test/libsolidity/ErrorCheck.h b/test/libsolidity/ErrorCheck.h
index 8ad81f85..c3a2f522 100644
--- a/test/libsolidity/ErrorCheck.h
+++ b/test/libsolidity/ErrorCheck.h
@@ -21,7 +21,7 @@
#pragma once
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <vector>
#include <tuple>
@@ -30,10 +30,10 @@ namespace dev
{
namespace solidity
{
-bool searchErrorMessage(Error const& _err, std::string const& _substr);
+bool searchErrorMessage(langutil::Error const& _err, std::string const& _substr);
/// Checks that all provided errors are of the given type and have a given substring in their
/// description.
/// If the expectations are not met, returns a nonempty description, otherwise an empty string.
-std::string searchErrors(ErrorList const& _errors, std::vector<std::pair<Error::Type, std::string>> const& _expectations);
+std::string searchErrors(langutil::ErrorList const& _errors, std::vector<std::pair<langutil::Error::Type, std::string>> const& _expectations);
}
}
diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp
index 4887dd5b..601948bc 100644
--- a/test/libsolidity/GasMeter.cpp
+++ b/test/libsolidity/GasMeter.cpp
@@ -26,9 +26,10 @@
#include <libevmasm/PathGasMeter.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/interface/GasEstimator.h>
-#include <libsolidity/interface/SourceReferenceFormatter.h>
+#include <liblangutil/SourceReferenceFormatter.h>
using namespace std;
+using namespace langutil;
using namespace dev::eth;
using namespace dev::solidity;
using namespace dev::test;
diff --git a/test/libsolidity/Imports.cpp b/test/libsolidity/Imports.cpp
index dc33d577..abd659b6 100644
--- a/test/libsolidity/Imports.cpp
+++ b/test/libsolidity/Imports.cpp
@@ -23,7 +23,7 @@
#include <test/libsolidity/ErrorCheck.h>
#include <test/Options.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <libsolidity/interface/CompilerStack.h>
#include <boost/test/unit_test.hpp>
diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp
index a9ce6e49..31d21490 100644
--- a/test/libsolidity/InlineAssembly.cpp
+++ b/test/libsolidity/InlineAssembly.cpp
@@ -23,8 +23,8 @@
#include <test/Options.h>
#include <libsolidity/interface/AssemblyStack.h>
-#include <libsolidity/parsing/Scanner.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Scanner.h>
+#include <liblangutil/Exceptions.h>
#include <libsolidity/ast/AST.h>
#include <test/libsolidity/ErrorCheck.h>
#include <libevmasm/Assembly.h>
@@ -36,6 +36,7 @@
#include <memory>
using namespace std;
+using namespace langutil;
namespace dev
{
diff --git a/test/libsolidity/SMTChecker.cpp b/test/libsolidity/SMTChecker.cpp
index 195004cb..a49618bd 100644
--- a/test/libsolidity/SMTChecker.cpp
+++ b/test/libsolidity/SMTChecker.cpp
@@ -25,6 +25,7 @@
#include <string>
using namespace std;
+using namespace langutil;
namespace dev
{
@@ -55,599 +56,6 @@ protected:
BOOST_FIXTURE_TEST_SUITE(SMTChecker, SMTCheckerFramework)
-BOOST_AUTO_TEST_CASE(smoke_test)
-{
- string text = R"(
- contract C { }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(simple_overflow)
-{
- string text = R"(
- contract C {
- function f(uint a, uint b) public pure returns (uint) { return a + b; }
- }
- )";
- CHECK_WARNING(text, "Overflow (resulting value larger than");
-}
-
-BOOST_AUTO_TEST_CASE(warn_on_typecast)
-{
- string text = R"(
- contract C {
- function f() public pure returns (uint) {
- return uint8(1);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion checker does not yet implement this expression.");
-}
-
-BOOST_AUTO_TEST_CASE(warn_on_struct)
-{
- string text = R"(
- pragma experimental ABIEncoderV2;
- contract C {
- struct A { uint a; uint b; }
- function f() public pure returns (A memory) {
- return A({ a: 1, b: 2 });
- }
- }
- )";
- CHECK_WARNING_ALLOW_MULTI(text, (vector<string>{
- "Experimental feature",
- "Assertion checker does not yet implement this expression.",
- "Assertion checker does not yet support the type of this variable."
- }));
-}
-
-BOOST_AUTO_TEST_CASE(simple_assert)
-{
- string text = R"(
- contract C {
- function f(uint a) public pure { assert(a == 2); }
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
-}
-
-BOOST_AUTO_TEST_CASE(simple_assert_with_require)
-{
- string text = R"(
- contract C {
- function f(uint a) public pure { require(a < 10); assert(a < 20); }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(assignment_in_declaration)
-{
- string text = R"(
- contract C {
- function f() public pure { uint a = 2; assert(a == 2); }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(branches_merge_variables)
-{
- // Branch does not touch variable a
- string text = R"(
- contract C {
- function f(uint x) public pure {
- uint a = 3;
- if (x > 10) {
- }
- assert(a == 3);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- // Positive branch touches variable a, but assertion should still hold.
- text = R"(
- contract C {
- function f(uint x) public pure {
- uint a = 3;
- if (x > 10) {
- a = 3;
- }
- assert(a == 3);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- // Negative branch touches variable a, but assertion should still hold.
- text = R"(
- contract C {
- function f(uint x) public pure {
- uint a = 3;
- if (x > 10) {
- } else {
- a = 3;
- }
- assert(a == 3);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- // Variable is not merged, if it is only read.
- text = R"(
- contract C {
- function f(uint x) public pure {
- uint a = 3;
- if (x > 10) {
- assert(a == 3);
- } else {
- assert(a == 3);
- }
- assert(a == 3);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- // Variable is reset in both branches
- text = R"(
- contract C {
- function f(uint x) public pure {
- uint a = 2;
- if (x > 10) {
- a = 3;
- } else {
- a = 3;
- }
- assert(a == 3);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- // Variable is reset in both branches
- text = R"(
- contract C {
- function f(uint x) public pure {
- uint a = 2;
- if (x > 10) {
- a = 3;
- } else {
- a = 4;
- }
- assert(a >= 3);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(branches_assert_condition)
-{
- string text = R"(
- contract C {
- function f(uint x) public pure {
- if (x > 10) {
- assert(x > 9);
- }
- else
- {
- assert(x < 11);
- }
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- text = R"(
- contract C {
- function f(uint x) public pure {
- if (x > 10) {
- assert(x > 9);
- }
- else if (x > 2)
- {
- assert(x <= 10 && x > 2);
- }
- else
- {
- assert(0 <= x && x <= 2);
- }
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(ways_to_merge_variables)
-{
- string text = R"(
- contract C {
- function f(uint x) public pure {
- uint a = 3;
- if (x > 10) {
- a++;
- }
- assert(a == 3);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
- text = R"(
- contract C {
- function f(uint x) public pure {
- uint a = 3;
- if (x > 10) {
- ++a;
- }
- assert(a == 3);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
- text = R"(
- contract C {
- function f(uint x) public pure {
- uint a = 3;
- if (x > 10) {
- a = 5;
- }
- assert(a == 3);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
-}
-
-BOOST_AUTO_TEST_CASE(bool_simple)
-{
- string text = R"(
- contract C {
- function f(bool x) public pure {
- assert(x);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
- text = R"(
- contract C {
- function f(bool x, bool y) public pure {
- assert(x == y);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
- text = R"(
- contract C {
- function f(bool x, bool y) public pure {
- bool z = x || y;
- assert(!(x && y) || z);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- text = R"(
- contract C {
- function f(bool x) public pure {
- if (x) {
- assert(x);
- } else {
- assert(!x);
- }
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- text = R"(
- contract C {
- function f(bool x) public pure {
- bool y = x;
- assert(x == y);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- text = R"(
- contract C {
- function f(bool x) public pure {
- require(x);
- bool y;
- y = false;
- assert(x || y);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(bool_int_mixed)
-{
- string text = R"(
- contract C {
- function f(bool x) public pure {
- uint a;
- if (x)
- a = 1;
- assert(!x || a > 0);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- text = R"(
- contract C {
- function f(bool x, uint a) public pure {
- require(!x || a > 0);
- uint b = a;
- assert(!x || b > 0);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- text = R"(
- contract C {
- function f(bool x, bool y) public pure {
- uint a;
- if (x) {
- if (y) {
- a = 0;
- } else {
- a = 1;
- }
- } else {
- if (y) {
- a = 1;
- } else {
- a = 0;
- }
- }
- bool xor_x_y = (x && !y) || (!x && y);
- assert(!xor_x_y || a > 0);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(storage_value_vars)
-{
- string text = R"(
- contract C
- {
- address a;
- bool b;
- uint c;
- function f(uint x) public {
- if (x == 0)
- {
- a = 0x0000000000000000000000000000000000000100;
- b = true;
- }
- else
- {
- a = 0x0000000000000000000000000000000000000200;
- b = false;
- }
- assert(a > 0x0000000000000000000000000000000000000000 && b);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
- text = R"(
- contract C
- {
- address a;
- bool b;
- uint c;
- function f() public view {
- assert(c > 0);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
- text = R"(
- contract C
- {
- function f(uint x) public {
- if (x == 0)
- {
- a = 0x0000000000000000000000000000000000000100;
- b = true;
- }
- else
- {
- a = 0x0000000000000000000000000000000000000200;
- b = false;
- }
- assert(b == (a < 0x0000000000000000000000000000000000000200));
- }
-
- function g() public view {
- require(a < 0x0000000000000000000000000000000000000100);
- assert(c >= 0);
- }
- address a;
- bool b;
- uint c;
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- text = R"(
- contract C
- {
- function f() public view {
- assert(c > 0);
- }
- uint c;
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
-
-}
-
-BOOST_AUTO_TEST_CASE(while_loop_simple)
-{
- // Check that variables are cleared
- string text = R"(
- contract C {
- function f(uint x) public pure {
- x = 2;
- while (x > 1) {
- x = 2;
- }
- assert(x == 2);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
- // Check that condition is assumed.
- text = R"(
- contract C {
- function f(uint x) public pure {
- while (x == 2) {
- assert(x == 2);
- }
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- // Check that condition is not assumed after the body anymore
- text = R"(
- contract C {
- function f(uint x) public pure {
- while (x == 2) {
- }
- assert(x == 2);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
- // Check that negation of condition is not assumed after the body anymore
- text = R"(
- contract C {
- function f(uint x) public pure {
- while (x == 2) {
- }
- assert(x != 2);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
- // Check that side-effects of condition are taken into account
- text = R"(
- contract C {
- function f(uint x, uint y) public pure {
- x = 7;
- while ((x = y) > 0) {
- }
- assert(x == 7);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation happens here");
-}
-
-BOOST_AUTO_TEST_CASE(constant_condition)
-{
- string text = R"(
- contract C {
- function f(uint x) public pure {
- if (x >= 0) { revert(); }
- }
- }
- )";
- CHECK_WARNING_ALLOW_MULTI(text, (vector<string>{
- "Condition is always true",
- "Assertion checker does not yet implement this type of function call"
- }));
- text = R"(
- contract C {
- function f(uint x) public pure {
- if (x >= 10) { if (x < 10) { revert(); } }
- }
- }
- )";
- CHECK_WARNING_ALLOW_MULTI(text, (vector<string>{
- "Condition is always false",
- "Assertion checker does not yet implement this type of function call"
- }));
- // a plain literal constant is fine
- text = R"(
- contract C {
- function f(uint) public pure {
- if (true) { revert(); }
- }
- }
- )";
- CHECK_WARNING(text, "Assertion checker does not yet implement this type of function call");
-}
-
-
-BOOST_AUTO_TEST_CASE(for_loop)
-{
- string text = R"(
- contract C {
- function f(uint x) public pure {
- require(x == 2);
- for (;;) {}
- assert(x == 2);
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- text = R"(
- contract C {
- function f(uint x) public pure {
- for (; x == 2; ) {
- assert(x == 2);
- }
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- text = R"(
- contract C {
- function f(uint x) public pure {
- for (uint y = 2; x < 10; ) {
- assert(y == 2);
- }
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- text = R"(
- contract C {
- function f(uint x) public pure {
- for (uint y = 2; x < 10; y = 3) {
- assert(y == 2);
- }
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation");
- text = R"(
- contract C {
- function f(uint x) public pure {
- uint y;
- for (y = 2; x < 10; ) {
- y = 3;
- }
- assert(y == 3);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation");
- text = R"(
- contract C {
- function f(uint x) public pure {
- uint y;
- for (y = 2; x < 10; ) {
- y = 3;
- }
- assert(y == 2);
- }
- }
- )";
- CHECK_WARNING(text, "Assertion violation");
-}
-
BOOST_AUTO_TEST_CASE(division)
{
string text = R"(
diff --git a/test/libsolidity/SMTCheckerJSONTest.cpp b/test/libsolidity/SMTCheckerJSONTest.cpp
new file mode 100644
index 00000000..6e1329a9
--- /dev/null
+++ b/test/libsolidity/SMTCheckerJSONTest.cpp
@@ -0,0 +1,128 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <test/libsolidity/SMTCheckerJSONTest.h>
+#include <test/Options.h>
+#include <libsolidity/interface/StandardCompiler.h>
+#include <libdevcore/JSON.h>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/join.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/throw_exception.hpp>
+#include <fstream>
+#include <memory>
+#include <stdexcept>
+#include <sstream>
+
+using namespace dev;
+using namespace solidity;
+using namespace dev::solidity::test;
+using namespace dev::solidity::test::formatting;
+using namespace std;
+using namespace boost::unit_test;
+
+SMTCheckerTest::SMTCheckerTest(string const& _filename)
+: SyntaxTest(_filename)
+{
+ BOOST_REQUIRE_MESSAGE(boost::algorithm::ends_with(_filename, ".sol"), "Invalid test contract file name: \"" + _filename + "\".");
+
+ string jsonFilename = _filename.substr(0, _filename.size() - 4) + ".json";
+ BOOST_CHECK(jsonParseFile(jsonFilename, m_smtResponses));
+ BOOST_CHECK(m_smtResponses.isObject());
+}
+
+bool SMTCheckerTest::run(ostream& _stream, string const& _linePrefix, bool const _formatted)
+{
+ StandardCompiler compiler;
+
+ // Run the compiler and retrieve the smtlib2queries (1st run)
+ string versionPragma = "pragma solidity >=0.0;\n";
+ Json::Value input = buildJson(versionPragma);
+ Json::Value result = compiler.compile(input);
+
+ // This is the list of query hashes requested by the 1st run
+ vector<string> outHashes = hashesFromJson(result, "auxiliaryInputRequested", "smtlib2queries");
+
+ // This is the list of responses provided in the test
+ string auxInput("auxiliaryInput");
+ BOOST_CHECK(m_smtResponses.isMember(auxInput));
+ vector<string> inHashes = hashesFromJson(m_smtResponses, auxInput, "smtlib2responses");
+
+ // Ensure that the provided list matches the requested one
+ BOOST_CHECK_MESSAGE(
+ outHashes == inHashes,
+ "SMT query hashes differ: " + boost::algorithm::join(outHashes, ", ") + " x " + boost::algorithm::join(inHashes, ", ")
+ );
+
+ // Rerun the compiler with the provided hashed (2nd run)
+ input[auxInput] = m_smtResponses[auxInput];
+ Json::Value endResult = compiler.compile(input);
+
+ BOOST_CHECK(endResult.isMember("errors"));
+ Json::Value const& errors = endResult["errors"];
+ for (auto const& error: errors)
+ {
+ BOOST_CHECK(error.isMember("type") && error["type"].isString());
+ BOOST_CHECK(error.isMember("message") && error["message"].isString());
+ if (!error.isMember("sourceLocation"))
+ continue;
+ Json::Value const& location = error["sourceLocation"];
+ BOOST_CHECK(location.isMember("start") && location["start"].isInt());
+ BOOST_CHECK(location.isMember("end") && location["end"].isInt());
+ int start = location["start"].asInt();
+ int end = location["end"].asInt();
+ if (start >= static_cast<int>(versionPragma.size()))
+ start -= versionPragma.size();
+ if (end >= static_cast<int>(versionPragma.size()))
+ end -= versionPragma.size();
+ m_errorList.emplace_back(SyntaxTestError{
+ error["type"].asString(),
+ error["message"].asString(),
+ start,
+ end
+ });
+ }
+
+ return printExpectationAndError(_stream, _linePrefix, _formatted);
+}
+
+vector<string> SMTCheckerTest::hashesFromJson(Json::Value const& _jsonObj, string const& _auxInput, string const& _smtlib)
+{
+ vector<string> hashes;
+ Json::Value const& auxInputs = _jsonObj[_auxInput];
+ if (!!auxInputs)
+ {
+ Json::Value const& smtlib = auxInputs[_smtlib];
+ if (!!smtlib)
+ for (auto const& hashString: smtlib.getMemberNames())
+ hashes.push_back(hashString);
+ }
+ return hashes;
+}
+
+Json::Value SMTCheckerTest::buildJson(string const& _extra)
+{
+ string language = "\"language\": \"Solidity\"";
+ string sourceName = "\"A\"";
+ string sourceContent = "\"" + _extra + m_source + "\"";
+ string sourceObj = "{ \"content\": " + sourceContent + "}";
+ string sources = " \"sources\": { " + sourceName + ": " + sourceObj + "}";
+ string input = "{" + language + ", " + sources + "}";
+ Json::Value source;
+ BOOST_REQUIRE(jsonParse(input, source));
+ return source;
+}
diff --git a/test/libsolidity/SMTCheckerJSONTest.h b/test/libsolidity/SMTCheckerJSONTest.h
new file mode 100644
index 00000000..cf41acac
--- /dev/null
+++ b/test/libsolidity/SMTCheckerJSONTest.h
@@ -0,0 +1,53 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include <test/libsolidity/SyntaxTest.h>
+
+#include <libdevcore/JSON.h>
+
+#include <string>
+
+namespace dev
+{
+namespace solidity
+{
+namespace test
+{
+
+class SMTCheckerTest: public SyntaxTest
+{
+public:
+ static std::unique_ptr<TestCase> create(std::string const& _filename)
+ {
+ return std::unique_ptr<TestCase>(new SMTCheckerTest(_filename));
+ }
+ SMTCheckerTest(std::string const& _filename);
+
+ bool run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
+
+private:
+ std::vector<std::string> hashesFromJson(Json::Value const& _jsonObj, std::string const& _auxInput, std::string const& _smtlib);
+ Json::Value buildJson(std::string const& _extra);
+
+ Json::Value m_smtResponses;
+};
+
+}
+}
+}
diff --git a/test/libsolidity/SemVerMatcher.cpp b/test/libsolidity/SemVerMatcher.cpp
index 43951f73..2e147847 100644
--- a/test/libsolidity/SemVerMatcher.cpp
+++ b/test/libsolidity/SemVerMatcher.cpp
@@ -23,11 +23,12 @@
#include <string>
#include <vector>
#include <tuple>
-#include <libsolidity/parsing/Scanner.h>
+#include <liblangutil/Scanner.h>
#include <libsolidity/analysis/SemVerHandler.h>
#include <test/Options.h>
using namespace std;
+using namespace langutil;
namespace dev
{
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 87646737..e9667483 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -25,8 +25,8 @@
#include <test/Options.h>
-#include <libsolidity/interface/Exceptions.h>
-#include <libsolidity/interface/EVMVersion.h>
+#include <liblangutil/Exceptions.h>
+#include <liblangutil/EVMVersion.h>
#include <libevmasm/Assembly.h>
@@ -9388,6 +9388,25 @@ BOOST_AUTO_TEST_CASE(using_for_by_name)
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7)));
}
+BOOST_AUTO_TEST_CASE(bound_function_in_function)
+{
+ char const* sourceCode = R"(
+ library L {
+ function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }
+ }
+ contract C {
+ using L for *;
+ function f() public returns (uint) {
+ return t.g();
+ }
+ function t() public pure returns (uint) { return 7; }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "L");
+ compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{"L", m_contractAddress}});
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7)));
+}
+
BOOST_AUTO_TEST_CASE(bound_function_in_var)
{
char const* sourceCode = R"(
@@ -14043,6 +14062,21 @@ BOOST_AUTO_TEST_CASE(flipping_sign_tests)
ABI_CHECK(callContractFunction("f()"), encodeArgs(true));
}
+BOOST_AUTO_TEST_CASE(external_public_override)
+{
+ char const* sourceCode = R"(
+ contract A {
+ function f() external returns (uint) { return 1; }
+ }
+ contract B is A {
+ function f() public returns (uint) { return 2; }
+ function g() public returns (uint) { return f(); }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(2));
+ ABI_CHECK(callContractFunction("g()"), encodeArgs(2));
+}
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityExecutionFramework.h b/test/libsolidity/SolidityExecutionFramework.h
index 12687dd1..cedbf51a 100644
--- a/test/libsolidity/SolidityExecutionFramework.h
+++ b/test/libsolidity/SolidityExecutionFramework.h
@@ -27,8 +27,8 @@
#include <test/ExecutionFramework.h>
#include <libsolidity/interface/CompilerStack.h>
-#include <libsolidity/interface/Exceptions.h>
-#include <libsolidity/interface/SourceReferenceFormatter.h>
+#include <liblangutil/Exceptions.h>
+#include <liblangutil/SourceReferenceFormatter.h>
namespace dev
{
@@ -72,13 +72,13 @@ public:
m_compiler.setOptimiserSettings(m_optimize, m_optimizeRuns);
if (!m_compiler.compile())
{
- auto scannerFromSourceName = [&](std::string const& _sourceName) -> solidity::Scanner const& { return m_compiler.scanner(_sourceName); };
- SourceReferenceFormatter formatter(std::cerr, scannerFromSourceName);
+ auto scannerFromSourceName = [&](std::string const& _sourceName) -> langutil::Scanner const& { return m_compiler.scanner(_sourceName); };
+ langutil::SourceReferenceFormatter formatter(std::cerr, scannerFromSourceName);
for (auto const& error: m_compiler.errors())
formatter.printExceptionInformation(
*error,
- (error->type() == Error::Type::Warning) ? "Warning" : "Error"
+ (error->type() == langutil::Error::Type::Warning) ? "Warning" : "Error"
);
BOOST_ERROR("Compiling contract failed");
}
diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp
index 309cbf0b..a68eb3df 100644
--- a/test/libsolidity/SolidityExpressionCompiler.cpp
+++ b/test/libsolidity/SolidityExpressionCompiler.cpp
@@ -22,17 +22,18 @@
#include <string>
-#include <libsolidity/parsing/Scanner.h>
+#include <liblangutil/Scanner.h>
#include <libsolidity/parsing/Parser.h>
#include <libsolidity/analysis/NameAndTypeResolver.h>
#include <libsolidity/codegen/CompilerContext.h>
#include <libsolidity/codegen/ExpressionCompiler.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/analysis/TypeChecker.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
#include <test/Options.h>
using namespace std;
+using namespace langutil;
namespace dev
{
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 5ec010c7..75726027 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -33,6 +33,7 @@
#include <string>
using namespace std;
+using namespace langutil;
namespace dev
{
diff --git a/test/libsolidity/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp
index d77050cb..d930f697 100644
--- a/test/libsolidity/SolidityNatspecJSON.cpp
+++ b/test/libsolidity/SolidityNatspecJSON.cpp
@@ -24,9 +24,11 @@
#include <string>
#include <libdevcore/JSON.h>
#include <libsolidity/interface/CompilerStack.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <liblangutil/Exceptions.h>
#include <libdevcore/Exceptions.h>
+using namespace langutil;
+
namespace dev
{
namespace solidity
diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp
index 5432e9b5..3534dd5b 100644
--- a/test/libsolidity/SolidityParser.cpp
+++ b/test/libsolidity/SolidityParser.cpp
@@ -22,13 +22,14 @@
#include <string>
#include <memory>
-#include <libsolidity/parsing/Scanner.h>
+#include <liblangutil/Scanner.h>
#include <libsolidity/parsing/Parser.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
#include <test/Options.h>
#include <test/libsolidity/ErrorCheck.h>
using namespace std;
+using namespace langutil;
namespace dev
{
diff --git a/test/libsolidity/SolidityScanner.cpp b/test/libsolidity/SolidityScanner.cpp
index 6965d886..02d91d32 100644
--- a/test/libsolidity/SolidityScanner.cpp
+++ b/test/libsolidity/SolidityScanner.cpp
@@ -20,10 +20,11 @@
* Unit tests for the solidity scanner.
*/
-#include <libsolidity/parsing/Scanner.h>
+#include <liblangutil/Scanner.h>
#include <boost/test/unit_test.hpp>
using namespace std;
+using namespace langutil;
namespace dev
{
@@ -87,6 +88,7 @@ BOOST_AUTO_TEST_CASE(string_escape_illegal)
Scanner scanner(CharStream(" bla \"\\x6rf\" (illegalescape)"));
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Identifier);
BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
+ BOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalEscapeSequence);
BOOST_CHECK_EQUAL(scanner.currentLiteral(), "");
// TODO recovery from illegal tokens should be improved
BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
@@ -485,28 +487,32 @@ BOOST_AUTO_TEST_CASE(invalid_short_hex_literal)
{
Scanner scanner(CharStream("{ hex\"00112233F\""));
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);
- BOOST_CHECK_EQUAL(scanner.next(), Token::IllegalHex);
+ BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
+ BOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalHexString);
}
BOOST_AUTO_TEST_CASE(invalid_hex_literal_with_space)
{
Scanner scanner(CharStream("{ hex\"00112233FF \""));
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);
- BOOST_CHECK_EQUAL(scanner.next(), Token::IllegalHex);
+ BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
+ BOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalHexString);
}
BOOST_AUTO_TEST_CASE(invalid_hex_literal_with_wrong_quotes)
{
Scanner scanner(CharStream("{ hex\"00112233FF'"));
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);
- BOOST_CHECK_EQUAL(scanner.next(), Token::IllegalHex);
+ BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
+ BOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalHexString);
}
BOOST_AUTO_TEST_CASE(invalid_hex_literal_nonhex_string)
{
Scanner scanner(CharStream("{ hex\"hello\""));
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace);
- BOOST_CHECK_EQUAL(scanner.next(), Token::IllegalHex);
+ BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal);
+ BOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalHexString);
}
// COMMENTS
diff --git a/test/libsolidity/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp
index 6f9d4ce8..c839afd4 100644
--- a/test/libsolidity/SolidityTypes.cpp
+++ b/test/libsolidity/SolidityTypes.cpp
@@ -26,6 +26,7 @@
#include <boost/test/unit_test.hpp>
using namespace std;
+using namespace langutil;
namespace dev
{
diff --git a/test/libsolidity/SyntaxTest.cpp b/test/libsolidity/SyntaxTest.cpp
index 91d1681f..c47ea599 100644
--- a/test/libsolidity/SyntaxTest.cpp
+++ b/test/libsolidity/SyntaxTest.cpp
@@ -25,6 +25,7 @@
#include <stdexcept>
using namespace dev;
+using namespace langutil;
using namespace solidity;
using namespace dev::solidity::test;
using namespace dev::solidity::test::formatting;
@@ -91,6 +92,11 @@ bool SyntaxTest::run(ostream& _stream, string const& _linePrefix, bool const _fo
});
}
+ return printExpectationAndError(_stream, _linePrefix, _formatted);
+}
+
+bool SyntaxTest::printExpectationAndError(ostream& _stream, string const& _linePrefix, bool const _formatted)
+{
if (m_expectations != m_errorList)
{
string nextIndentLevel = _linePrefix + " ";
diff --git a/test/libsolidity/SyntaxTest.h b/test/libsolidity/SyntaxTest.h
index e9e36aa6..12c14087 100644
--- a/test/libsolidity/SyntaxTest.h
+++ b/test/libsolidity/SyntaxTest.h
@@ -19,8 +19,8 @@
#include <test/libsolidity/AnalysisFramework.h>
#include <test/libsolidity/FormattedScope.h>
-#include <test/libsolidity/TestCase.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <test/TestCase.h>
+#include <liblangutil/Exceptions.h>
#include <iosfwd>
#include <string>
@@ -57,17 +57,17 @@ public:
{ return std::unique_ptr<TestCase>(new SyntaxTest(_filename)); }
SyntaxTest(std::string const& _filename);
- virtual bool run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
+ bool run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
- virtual void printSource(std::ostream &_stream, std::string const &_linePrefix = "", bool const _formatted = false) const override;
- virtual void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override
+ void printSource(std::ostream &_stream, std::string const &_linePrefix = "", bool const _formatted = false) const override;
+ void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override
{
if (!m_errorList.empty())
printErrorList(_stream, m_errorList, _linePrefix, false);
}
static std::string errorMessage(Exception const& _e);
-private:
+protected:
static void printErrorList(
std::ostream& _stream,
std::vector<SyntaxTestError> const& _errors,
@@ -75,6 +75,8 @@ private:
bool const _formatted = false
);
+ virtual bool printExpectationAndError(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false);
+
static std::vector<SyntaxTestError> parseExpectations(std::istream& _stream);
std::string m_source;
diff --git a/test/libsolidity/ViewPureChecker.cpp b/test/libsolidity/ViewPureChecker.cpp
index b7ea1efc..64e52604 100644
--- a/test/libsolidity/ViewPureChecker.cpp
+++ b/test/libsolidity/ViewPureChecker.cpp
@@ -28,6 +28,7 @@
#include <tuple>
using namespace std;
+using namespace langutil;
namespace dev
{
diff --git a/test/libsolidity/smtCheckerTests/complex/warn_on_struct.sol b/test/libsolidity/smtCheckerTests/complex/warn_on_struct.sol
new file mode 100644
index 00000000..6d9afe7c
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/complex/warn_on_struct.sol
@@ -0,0 +1,14 @@
+pragma experimental SMTChecker;
+
+contract C {
+ struct A { uint a; uint b; }
+ function f() public pure returns (uint) {
+ A memory a = A({ a: 1, b: 2 });
+ }
+}
+// ----
+// Warning: (133-143): Unused local variable.
+// Warning: (133-143): Assertion checker does not yet support the type of this variable.
+// Warning: (146-163): Assertion checker does not yet implement this expression.
+// Warning: (146-163): Internal error: Expression undefined for SMT solver.
+// Warning: (146-163): Assertion checker does not yet implement this type.
diff --git a/test/libsolidity/smtCheckerTests/complex/warn_on_typecast.sol b/test/libsolidity/smtCheckerTests/complex/warn_on_typecast.sol
new file mode 100644
index 00000000..be785414
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/complex/warn_on_typecast.sol
@@ -0,0 +1,8 @@
+pragma experimental SMTChecker;
+contract C {
+ function f() public pure returns (uint) {
+ return uint8(1);
+ }
+}
+// ----
+// Warning: (106-114): Assertion checker does not yet implement this expression.
diff --git a/test/libsolidity/smtCheckerTests/control_flow/assignment_in_declaration.sol b/test/libsolidity/smtCheckerTests/control_flow/assignment_in_declaration.sol
new file mode 100644
index 00000000..0c701672
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/control_flow/assignment_in_declaration.sol
@@ -0,0 +1,4 @@
+pragma experimental SMTChecker;
+contract C {
+ function f() public pure { uint a = 2; assert(a == 2); }
+}
diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_assert_condition_1.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_assert_condition_1.sol
new file mode 100644
index 00000000..64f6e012
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/control_flow/branches_assert_condition_1.sol
@@ -0,0 +1,12 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ if (x > 10) {
+ assert(x > 9);
+ }
+ else
+ {
+ assert(x < 11);
+ }
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_assert_condition_2.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_assert_condition_2.sol
new file mode 100644
index 00000000..e39ab844
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/control_flow/branches_assert_condition_2.sol
@@ -0,0 +1,16 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ if (x > 10) {
+ assert(x > 9);
+ }
+ else if (x > 2)
+ {
+ assert(x <= 10 && x > 2);
+ }
+ else
+ {
+ assert(0 <= x && x <= 2);
+ }
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_1.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_1.sol
new file mode 100644
index 00000000..f93e32e4
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_1.sol
@@ -0,0 +1,10 @@
+pragma experimental SMTChecker;
+// Branch does not touch variable a
+contract C {
+ function f(uint x) public pure {
+ uint a = 3;
+ if (x > 10) {
+ }
+ assert(a == 3);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_2.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_2.sol
new file mode 100644
index 00000000..c00ef787
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_2.sol
@@ -0,0 +1,11 @@
+pragma experimental SMTChecker;
+// Positive branch touches variable a, but assertion should still hold.
+contract C {
+ function f(uint x) public pure {
+ uint a = 3;
+ if (x > 10) {
+ a = 3;
+ }
+ assert(a == 3);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_3.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_3.sol
new file mode 100644
index 00000000..4e18aa88
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_3.sol
@@ -0,0 +1,12 @@
+pragma experimental SMTChecker;
+// Negative branch touches variable a, but assertion should still hold.
+contract C {
+ function f(uint x) public pure {
+ uint a = 3;
+ if (x > 10) {
+ } else {
+ a = 3;
+ }
+ assert(a == 3);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_4.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_4.sol
new file mode 100644
index 00000000..e3a02704
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_4.sol
@@ -0,0 +1,13 @@
+pragma experimental SMTChecker;
+// Variable is not merged, if it is only read.
+contract C {
+ function f(uint x) public pure {
+ uint a = 3;
+ if (x > 10) {
+ assert(a == 3);
+ } else {
+ assert(a == 3);
+ }
+ assert(a == 3);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_5.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_5.sol
new file mode 100644
index 00000000..0bd1cf3a
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_5.sol
@@ -0,0 +1,13 @@
+pragma experimental SMTChecker;
+// Variable is reset in both branches
+contract C {
+ function f(uint x) public pure {
+ uint a = 2;
+ if (x > 10) {
+ a = 3;
+ } else {
+ a = 3;
+ }
+ assert(a == 3);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_6.sol b/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_6.sol
new file mode 100644
index 00000000..8e477179
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/control_flow/branches_merge_variables_6.sol
@@ -0,0 +1,13 @@
+pragma experimental SMTChecker;
+// Variable is reset in both branches
+contract C {
+ function f(uint x) public pure {
+ uint a = 2;
+ if (x > 10) {
+ a = 3;
+ } else {
+ a = 4;
+ }
+ assert(a >= 3);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_1.sol b/test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_1.sol
new file mode 100644
index 00000000..16d6fdfe
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_1.sol
@@ -0,0 +1,12 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ uint a = 3;
+ if (x > 10) {
+ a++;
+ }
+ assert(a == 3);
+ }
+}
+// ----
+// Warning: (159-173): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_2.sol b/test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_2.sol
new file mode 100644
index 00000000..e25ab20f
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_2.sol
@@ -0,0 +1,12 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ uint a = 3;
+ if (x > 10) {
+ ++a;
+ }
+ assert(a == 3);
+ }
+}
+// ----
+// Warning: (159-173): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_3.sol b/test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_3.sol
new file mode 100644
index 00000000..03ae7216
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/control_flow/ways_to_merge_variables_3.sol
@@ -0,0 +1,12 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ uint a = 3;
+ if (x > 10) {
+ a = 5;
+ }
+ assert(a == 3);
+ }
+}
+// ----
+// Warning: (161-175): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/functions/function_call_does_not_clear_local_vars.sol b/test/libsolidity/smtCheckerTests/functions/function_call_does_not_clear_local_vars.sol
new file mode 100644
index 00000000..b4260224
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/functions/function_call_does_not_clear_local_vars.sol
@@ -0,0 +1,13 @@
+pragma experimental SMTChecker;
+contract C {
+ function f() public {
+ uint a = 3;
+ this.f();
+ assert(a == 3);
+ f();
+ assert(a == 3);
+ }
+}
+// ----
+// Warning: (99-107): Assertion checker does not yet implement this type of function call.
+// Warning: (141-144): Assertion checker does not support recursive function calls.
diff --git a/test/libsolidity/smtCheckerTests/functions/functions_bound_1.sol b/test/libsolidity/smtCheckerTests/functions/functions_bound_1.sol
new file mode 100644
index 00000000..5e9722de
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/functions/functions_bound_1.sol
@@ -0,0 +1,19 @@
+pragma experimental SMTChecker;
+
+library L
+{
+ function add(uint x, uint y) internal pure returns (uint) {
+ require(x < 1000);
+ require(y < 1000);
+ return x + y;
+ }
+}
+
+contract C
+{
+ using L for uint;
+ function f(uint x) public pure {
+ uint y = x.add(999);
+ assert(y < 10000);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/functions/functions_bound_1_fail.sol b/test/libsolidity/smtCheckerTests/functions/functions_bound_1_fail.sol
new file mode 100644
index 00000000..99c785d0
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/functions/functions_bound_1_fail.sol
@@ -0,0 +1,21 @@
+pragma experimental SMTChecker;
+
+library L
+{
+ function add(uint x, uint y) internal pure returns (uint) {
+ require(x < 1000);
+ require(y < 1000);
+ return x + y;
+ }
+}
+
+contract C
+{
+ using L for uint;
+ function f(uint x) public pure {
+ uint y = x.add(999);
+ assert(y < 1000);
+ }
+}
+// ----
+// Warning: (261-277): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/functions/functions_library_1.sol b/test/libsolidity/smtCheckerTests/functions/functions_library_1.sol
new file mode 100644
index 00000000..2ceb9e60
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/functions/functions_library_1.sol
@@ -0,0 +1,18 @@
+pragma experimental SMTChecker;
+
+library L
+{
+ function add(uint x, uint y) internal pure returns (uint) {
+ require(x < 1000);
+ require(y < 1000);
+ return x + y;
+ }
+}
+
+contract C
+{
+ function f(uint x) public pure {
+ uint y = L.add(x, 999);
+ assert(y < 10000);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/functions/functions_library_1_fail.sol b/test/libsolidity/smtCheckerTests/functions/functions_library_1_fail.sol
new file mode 100644
index 00000000..32419700
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/functions/functions_library_1_fail.sol
@@ -0,0 +1,20 @@
+pragma experimental SMTChecker;
+
+library L
+{
+ function add(uint x, uint y) internal pure returns (uint) {
+ require(x < 1000);
+ require(y < 1000);
+ return x + y;
+ }
+}
+
+contract C
+{
+ function f(uint x) public pure {
+ uint y = L.add(x, 999);
+ assert(y < 1000);
+ }
+}
+// ----
+// Warning: (245-261): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_1.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_1.sol
new file mode 100644
index 00000000..8988efad
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/loops/for_loop_1.sol
@@ -0,0 +1,8 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ require(x == 2);
+ for (;;) {}
+ assert(x == 2);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_2.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_2.sol
new file mode 100644
index 00000000..58c9f3a7
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/loops/for_loop_2.sol
@@ -0,0 +1,8 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ for (; x == 2; ) {
+ assert(x == 2);
+ }
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_3.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_3.sol
new file mode 100644
index 00000000..8bf9bdc7
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/loops/for_loop_3.sol
@@ -0,0 +1,8 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ for (uint y = 2; x < 10; ) {
+ assert(y == 2);
+ }
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_4.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_4.sol
new file mode 100644
index 00000000..4d082026
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/loops/for_loop_4.sol
@@ -0,0 +1,10 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ for (uint y = 2; x < 10; y = 3) {
+ assert(y == 2);
+ }
+ }
+}
+// ----
+// Warning: (136-150): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_5.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_5.sol
new file mode 100644
index 00000000..2c84960f
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/loops/for_loop_5.sol
@@ -0,0 +1,12 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ uint y;
+ for (y = 2; x < 10; ) {
+ y = 3;
+ }
+ assert(y == 3);
+ }
+}
+// ----
+// Warning: (167-181): Assertion violation happens here\nNote that some information is erased after the execution of loops.\nYou can re-introduce information using require().
diff --git a/test/libsolidity/smtCheckerTests/loops/for_loop_6.sol b/test/libsolidity/smtCheckerTests/loops/for_loop_6.sol
new file mode 100644
index 00000000..90c4c328
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/loops/for_loop_6.sol
@@ -0,0 +1,12 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ uint y;
+ for (y = 2; x < 10; ) {
+ y = 3;
+ }
+ assert(y == 2);
+ }
+}
+// ----
+// Warning: (167-181): Assertion violation happens here\nNote that some information is erased after the execution of loops.\nYou can re-introduce information using require().
diff --git a/test/libsolidity/smtCheckerTests/loops/while_loop_simple_1.sol b/test/libsolidity/smtCheckerTests/loops/while_loop_simple_1.sol
new file mode 100644
index 00000000..074be86f
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/loops/while_loop_simple_1.sol
@@ -0,0 +1,13 @@
+pragma experimental SMTChecker;
+// Check that variables are cleared
+contract C {
+ function f(uint x) public pure {
+ x = 2;
+ while (x > 1) {
+ x = 2;
+ }
+ assert(x == 2);
+ }
+}
+// ----
+// Warning: (194-208): Assertion violation happens here\nNote that some information is erased after the execution of loops.\nYou can re-introduce information using require().
diff --git a/test/libsolidity/smtCheckerTests/loops/while_loop_simple_2.sol b/test/libsolidity/smtCheckerTests/loops/while_loop_simple_2.sol
new file mode 100644
index 00000000..92a3f0fe
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/loops/while_loop_simple_2.sol
@@ -0,0 +1,9 @@
+pragma experimental SMTChecker;
+// Check that condition is assumed.
+contract C {
+ function f(uint x) public pure {
+ while (x == 2) {
+ assert(x == 2);
+ }
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/loops/while_loop_simple_3.sol b/test/libsolidity/smtCheckerTests/loops/while_loop_simple_3.sol
new file mode 100644
index 00000000..a37df888
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/loops/while_loop_simple_3.sol
@@ -0,0 +1,11 @@
+pragma experimental SMTChecker;
+// Check that condition is not assumed after the body anymore
+contract C {
+ function f(uint x) public pure {
+ while (x == 2) {
+ }
+ assert(x == 2);
+ }
+}
+// ----
+// Warning: (187-201): Assertion violation happens here\nNote that some information is erased after the execution of loops.\nYou can re-introduce information using require().
diff --git a/test/libsolidity/smtCheckerTests/loops/while_loop_simple_4.sol b/test/libsolidity/smtCheckerTests/loops/while_loop_simple_4.sol
new file mode 100644
index 00000000..f71da865
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/loops/while_loop_simple_4.sol
@@ -0,0 +1,11 @@
+pragma experimental SMTChecker;
+// Check that negation of condition is not assumed after the body anymore
+contract C {
+ function f(uint x) public pure {
+ while (x == 2) {
+ }
+ assert(x != 2);
+ }
+}
+// ----
+// Warning: (199-213): Assertion violation happens here\nNote that some information is erased after the execution of loops.\nYou can re-introduce information using require().
diff --git a/test/libsolidity/smtCheckerTests/loops/while_loop_simple_5.sol b/test/libsolidity/smtCheckerTests/loops/while_loop_simple_5.sol
new file mode 100644
index 00000000..41559c99
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/loops/while_loop_simple_5.sol
@@ -0,0 +1,12 @@
+pragma experimental SMTChecker;
+// Check that side-effects of condition are taken into account
+contract C {
+ function f(uint x, uint y) public pure {
+ x = 7;
+ while ((x = y) > 0) {
+ }
+ assert(x == 7);
+ }
+}
+// ----
+// Warning: (216-230): Assertion violation happens here\nNote that some information is erased after the execution of loops.\nYou can re-introduce information using require().
diff --git a/test/libsolidity/smtCheckerTests/overflow/simple_overflow.sol b/test/libsolidity/smtCheckerTests/overflow/simple_overflow.sol
new file mode 100644
index 00000000..894ff1a4
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/overflow/simple_overflow.sol
@@ -0,0 +1,6 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint a, uint b) public pure returns (uint) { return a + b; }
+}
+// ----
+// Warning: (112-117): Overflow (resulting value larger than 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) happens here
diff --git a/test/libsolidity/smtCheckerTests/simple/smoke_test.sol b/test/libsolidity/smtCheckerTests/simple/smoke_test.sol
new file mode 100644
index 00000000..8b7b77da
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/simple/smoke_test.sol
@@ -0,0 +1,3 @@
+pragma experimental SMTChecker;
+contract C {
+}
diff --git a/test/libsolidity/smtCheckerTests/special/blockhash.sol b/test/libsolidity/smtCheckerTests/special/blockhash.sol
index 1c693914..59a52922 100644
--- a/test/libsolidity/smtCheckerTests/special/blockhash.sol
+++ b/test/libsolidity/smtCheckerTests/special/blockhash.sol
@@ -2,9 +2,13 @@ pragma experimental SMTChecker;
contract C
{
- function f() public payable {
+ function f(uint x) public payable {
+ assert(blockhash(x) > 0);
assert(blockhash(2) > 0);
+ uint y = x;
+ assert(blockhash(x) == blockhash(y));
}
}
// ----
-// Warning: (79-103): Assertion violation happens here
+// Warning: (85-109): Assertion violation happens here
+// Warning: (113-137): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/types/bool_int_mixed_1.sol b/test/libsolidity/smtCheckerTests/types/bool_int_mixed_1.sol
new file mode 100644
index 00000000..d611cc17
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/bool_int_mixed_1.sol
@@ -0,0 +1,9 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(bool x) public pure {
+ uint a;
+ if(x)
+ a = 1;
+ assert(!x || a > 0);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/types/bool_int_mixed_2.sol b/test/libsolidity/smtCheckerTests/types/bool_int_mixed_2.sol
new file mode 100644
index 00000000..24640c5a
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/bool_int_mixed_2.sol
@@ -0,0 +1,8 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(bool x, uint a) public pure {
+ require(!x || a > 0);
+ uint b = a;
+ assert(!x || b > 0);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/types/bool_int_mixed_3.sol b/test/libsolidity/smtCheckerTests/types/bool_int_mixed_3.sol
new file mode 100644
index 00000000..f872e82f
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/bool_int_mixed_3.sol
@@ -0,0 +1,21 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(bool x, bool y) public pure {
+ uint a;
+ if (x) {
+ if (y) {
+ a = 0;
+ } else {
+ a = 1;
+ }
+ } else {
+ if (y) {
+ a = 1;
+ } else {
+ a = 0;
+ }
+ }
+ bool xor_x_y = (x && !y) || (!x && y);
+ assert(!xor_x_y || a > 0);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/types/bool_simple_1.sol b/test/libsolidity/smtCheckerTests/types/bool_simple_1.sol
new file mode 100644
index 00000000..76b4b08b
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/bool_simple_1.sol
@@ -0,0 +1,8 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(bool x) public pure {
+ assert(x);
+ }
+}
+// ----
+// Warning: (90-99): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/types/bool_simple_2.sol b/test/libsolidity/smtCheckerTests/types/bool_simple_2.sol
new file mode 100644
index 00000000..5c166c02
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/bool_simple_2.sol
@@ -0,0 +1,8 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(bool x, bool y) public pure {
+ assert(x == y);
+ }
+}
+// ----
+// Warning: (98-112): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/types/bool_simple_3.sol b/test/libsolidity/smtCheckerTests/types/bool_simple_3.sol
new file mode 100644
index 00000000..1d2ab49f
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/bool_simple_3.sol
@@ -0,0 +1,7 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(bool x, bool y) public pure {
+ bool z = x || y;
+ assert(!(x && y) || z);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/types/bool_simple_4.sol b/test/libsolidity/smtCheckerTests/types/bool_simple_4.sol
new file mode 100644
index 00000000..c40404a4
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/bool_simple_4.sol
@@ -0,0 +1,10 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(bool x) public pure {
+ if(x) {
+ assert(x);
+ } else {
+ assert(!x);
+ }
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/types/bool_simple_5.sol b/test/libsolidity/smtCheckerTests/types/bool_simple_5.sol
new file mode 100644
index 00000000..4cecebbc
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/bool_simple_5.sol
@@ -0,0 +1,7 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(bool x) public pure {
+ bool y = x;
+ assert(x == y);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/types/bool_simple_6.sol b/test/libsolidity/smtCheckerTests/types/bool_simple_6.sol
new file mode 100644
index 00000000..90350bb6
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/bool_simple_6.sol
@@ -0,0 +1,9 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(bool x) public pure {
+ require(x);
+ bool y;
+ y = false;
+ assert(x || y);
+ }
+}
diff --git a/test/libsolidity/smtCheckerTests/types/storage_value_vars_1.sol b/test/libsolidity/smtCheckerTests/types/storage_value_vars_1.sol
new file mode 100644
index 00000000..84f6c77e
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/storage_value_vars_1.sol
@@ -0,0 +1,22 @@
+pragma experimental SMTChecker;
+contract C
+{
+ address a;
+ bool b;
+ uint c;
+ function f(uint x) public {
+ if (x == 0)
+ {
+ a = 0x0000000000000000000000000000000000000100;
+ b = true;
+ }
+ else
+ {
+ a = 0x0000000000000000000000000000000000000200;
+ b = false;
+ }
+ assert(a > 0x0000000000000000000000000000000000000000 && b);
+ }
+}
+// ----
+// Warning: (362-421): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/types/storage_value_vars_2.sol b/test/libsolidity/smtCheckerTests/types/storage_value_vars_2.sol
new file mode 100644
index 00000000..bceddb38
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/storage_value_vars_2.sol
@@ -0,0 +1,12 @@
+pragma experimental SMTChecker;
+contract C
+{
+ address a;
+ bool b;
+ uint c;
+ function f() public view {
+ assert(c > 0);
+ }
+}
+// ----
+// Warning: (123-136): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/types/storage_value_vars_3.sol b/test/libsolidity/smtCheckerTests/types/storage_value_vars_3.sol
new file mode 100644
index 00000000..39049b99
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/storage_value_vars_3.sol
@@ -0,0 +1,25 @@
+pragma experimental SMTChecker;
+contract C
+{
+ function f(uint x) public {
+ if (x == 0)
+ {
+ a = 0x0000000000000000000000000000000000000100;
+ b = true;
+ }
+ else
+ {
+ a = 0x0000000000000000000000000000000000000200;
+ b = false;
+ }
+ assert(b == (a < 0x0000000000000000000000000000000000000200));
+ }
+
+ function g() public view {
+ require(a < 0x0000000000000000000000000000000000000100);
+ assert(c >= 0);
+ }
+ address a;
+ bool b;
+ uint c;
+}
diff --git a/test/libsolidity/smtCheckerTests/types/storage_value_vars_4.sol b/test/libsolidity/smtCheckerTests/types/storage_value_vars_4.sol
new file mode 100644
index 00000000..88b6b0ae
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/types/storage_value_vars_4.sol
@@ -0,0 +1,10 @@
+pragma experimental SMTChecker;
+contract C
+{
+ function f() public view {
+ assert(c > 0);
+ }
+ uint c;
+}
+// ----
+// Warning: (84-97): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/verification_target/constant_condition_1.sol b/test/libsolidity/smtCheckerTests/verification_target/constant_condition_1.sol
new file mode 100644
index 00000000..b9fae4ee
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/verification_target/constant_condition_1.sol
@@ -0,0 +1,9 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ if (x >= 0) { revert(); }
+ }
+}
+// ----
+// Warning: (94-100): Condition is always true.
+// Warning: (104-112): Assertion checker does not yet implement this type of function call.
diff --git a/test/libsolidity/smtCheckerTests/verification_target/constant_condition_2.sol b/test/libsolidity/smtCheckerTests/verification_target/constant_condition_2.sol
new file mode 100644
index 00000000..aaa613ea
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/verification_target/constant_condition_2.sol
@@ -0,0 +1,9 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint x) public pure {
+ if (x >= 10) { if (x < 10) { revert(); } }
+ }
+}
+// ----
+// Warning: (109-115): Condition is always false.
+// Warning: (119-127): Assertion checker does not yet implement this type of function call.
diff --git a/test/libsolidity/smtCheckerTests/verification_target/constant_condition_3.sol b/test/libsolidity/smtCheckerTests/verification_target/constant_condition_3.sol
new file mode 100644
index 00000000..f22cd65e
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/verification_target/constant_condition_3.sol
@@ -0,0 +1,9 @@
+pragma experimental SMTChecker;
+// a plain literal constant is fine
+contract C {
+ function f(uint) public pure {
+ if (true) { revert(); }
+ }
+}
+// ----
+// Warning: (136-144): Assertion checker does not yet implement this type of function call.
diff --git a/test/libsolidity/smtCheckerTests/verification_target/simple_assert.sol b/test/libsolidity/smtCheckerTests/verification_target/simple_assert.sol
new file mode 100644
index 00000000..8bd6e61a
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/verification_target/simple_assert.sol
@@ -0,0 +1,6 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint a) public pure { assert(a == 2); }
+}
+// ----
+// Warning: (82-96): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTests/verification_target/simple_assert_with_require.sol b/test/libsolidity/smtCheckerTests/verification_target/simple_assert_with_require.sol
new file mode 100644
index 00000000..b66ae245
--- /dev/null
+++ b/test/libsolidity/smtCheckerTests/verification_target/simple_assert_with_require.sol
@@ -0,0 +1,4 @@
+pragma experimental SMTChecker;
+contract C {
+ function f(uint a) public pure { require(a < 10); assert(a < 20); }
+}
diff --git a/test/libsolidity/smtCheckerTestsJSON/multi.json b/test/libsolidity/smtCheckerTestsJSON/multi.json
new file mode 100644
index 00000000..2ed5150d
--- /dev/null
+++ b/test/libsolidity/smtCheckerTestsJSON/multi.json
@@ -0,0 +1,11 @@
+{
+ "auxiliaryInput":
+ {
+ "smtlib2responses":
+ {
+ "0x0426cd198d1e7123a28ffac2b759a666b86508ad046babf5166500dd6d8ed308": "unsat\n(error \"line 31 column 26: model is not available\")",
+ "0xa51ca41ae407f5a727f27101cbc079834743cc8955f9f585582034ca634953f6": "sat\n((|EVALEXPR_0| 1))",
+ "0xe9477f683ff20aa57fcb08682150f86c5917e1d4c0686b278ab9b73446d0682c": "sat\n((|EVALEXPR_0| 0))"
+ }
+ }
+}
diff --git a/test/libsolidity/smtCheckerTestsJSON/multi.sol b/test/libsolidity/smtCheckerTestsJSON/multi.sol
new file mode 100644
index 00000000..e0d69b1d
--- /dev/null
+++ b/test/libsolidity/smtCheckerTestsJSON/multi.sol
@@ -0,0 +1,13 @@
+pragma experimental SMTChecker;
+
+contract C
+{
+ function f(uint x) public pure {
+ assert(x > 0);
+ assert(x > 100);
+ assert(x >= 0);
+ }
+}
+// ----
+// Warning: (82-95): Assertion violation happens here
+// Warning: (99-114): Assertion violation happens here
diff --git a/test/libsolidity/smtCheckerTestsJSON/simple.json b/test/libsolidity/smtCheckerTestsJSON/simple.json
new file mode 100644
index 00000000..fd976b63
--- /dev/null
+++ b/test/libsolidity/smtCheckerTestsJSON/simple.json
@@ -0,0 +1,9 @@
+{
+ "auxiliaryInput":
+ {
+ "smtlib2responses":
+ {
+ "0xe9477f683ff20aa57fcb08682150f86c5917e1d4c0686b278ab9b73446d0682c": "sat\n((|EVALEXPR_0| 0))"
+ }
+ }
+}
diff --git a/test/libsolidity/smtCheckerTestsJSON/simple.sol b/test/libsolidity/smtCheckerTestsJSON/simple.sol
new file mode 100644
index 00000000..6bc7193d
--- /dev/null
+++ b/test/libsolidity/smtCheckerTestsJSON/simple.sol
@@ -0,0 +1,10 @@
+pragma experimental SMTChecker;
+
+contract C
+{
+ function f(uint x) public pure {
+ assert(x > 0);
+ }
+}
+// ----
+// Warning: (82-95): Assertion violation happens here
diff --git a/test/libsolidity/syntaxTests/bound/bound_all.sol b/test/libsolidity/syntaxTests/bound/bound_all.sol
new file mode 100644
index 00000000..29f55b88
--- /dev/null
+++ b/test/libsolidity/syntaxTests/bound/bound_all.sol
@@ -0,0 +1,10 @@
+library L {
+ function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }
+}
+contract C {
+ using L for *;
+ function f() public returns (uint) {
+ return t.g();
+ }
+ function t() public pure returns (uint) { return 7; }
+}
diff --git a/test/libsolidity/syntaxTests/bound/bound_call.sol b/test/libsolidity/syntaxTests/bound/bound_call.sol
new file mode 100644
index 00000000..281f19b4
--- /dev/null
+++ b/test/libsolidity/syntaxTests/bound/bound_call.sol
@@ -0,0 +1,7 @@
+library D { function double(uint self) internal pure returns (uint) { return 2*self; } }
+contract C {
+ using D for uint;
+ function f(uint a) public pure {
+ a.double();
+ }
+}
diff --git a/test/libsolidity/syntaxTests/bound/bound_no_call.sol b/test/libsolidity/syntaxTests/bound/bound_no_call.sol
new file mode 100644
index 00000000..dcb3c3c5
--- /dev/null
+++ b/test/libsolidity/syntaxTests/bound/bound_no_call.sol
@@ -0,0 +1,7 @@
+library D { function double(uint self) public pure returns (uint) { return 2*self; } }
+contract C {
+ using D for uint;
+ function f(uint a) public pure {
+ a.double;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/inheritance/override/external_turns_public_no_params.sol b/test/libsolidity/syntaxTests/inheritance/override/external_turns_public_no_params.sol
new file mode 100644
index 00000000..3d0394f5
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/override/external_turns_public_no_params.sol
@@ -0,0 +1,7 @@
+contract A {
+ function f() external pure {}
+}
+contract B is A {
+ function f() public pure {
+ }
+}
diff --git a/test/libsolidity/syntaxTests/inheritance/super_on_external.sol b/test/libsolidity/syntaxTests/inheritance/super_on_external.sol
new file mode 100644
index 00000000..21f3b1c2
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/super_on_external.sol
@@ -0,0 +1,10 @@
+contract A {
+ function f() external pure {}
+}
+contract B is A {
+ function f() public pure {
+ super.f();
+ }
+}
+// ----
+// TypeError: (106-113): Member "f" not found or not visible after argument-dependent lookup in contract super B.
diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/invalid_number.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/invalid_number.sol
index 715913de..b44d09e3 100644
--- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/invalid_number.sol
+++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/invalid_number.sol
@@ -7,4 +7,4 @@ contract C {
}
// ----
// ParserError: (72-73): Literal, identifier or instruction expected.
-// ParserError: (72-73): Expected primary expression.
+// ParserError: (72-73): Octal numbers not allowed.
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/182_equal_overload.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/182_equal_overload.sol
index cb9eb3fa..6f0c7df7 100644
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/182_equal_overload.sol
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/182_equal_overload.sol
@@ -4,4 +4,3 @@ contract C {
}
// ----
// DeclarationError: (17-66): Function with same name and arguments defined twice.
-// TypeError: (17-66): Overriding function visibility differs.
diff --git a/test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol b/test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol
index fb267ba3..352b5f8f 100644
--- a/test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol
+++ b/test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol
@@ -4,4 +4,4 @@ contract test {
}
}
// ----
-// ParserError: (44-47): Expected primary expression.
+// ParserError: (44-47): Identifier-start is not allowed at end of a number.
diff --git a/test/libsolidity/syntaxTests/string/string_new_line.sol b/test/libsolidity/syntaxTests/string/string_new_line.sol
index da2240f7..4cbc71a5 100644
--- a/test/libsolidity/syntaxTests/string/string_new_line.sol
+++ b/test/libsolidity/syntaxTests/string/string_new_line.sol
@@ -6,4 +6,4 @@ contract test {
}
}
// ----
-// ParserError: (100-112): Expected primary expression.
+// ParserError: (100-112): Expected string end-quote.
diff --git a/test/libsolidity/syntaxTests/string/string_terminated_by_backslash.sol b/test/libsolidity/syntaxTests/string/string_terminated_by_backslash.sol
index 3eaba6af..fba53a03 100644
--- a/test/libsolidity/syntaxTests/string/string_terminated_by_backslash.sol
+++ b/test/libsolidity/syntaxTests/string/string_terminated_by_backslash.sol
@@ -5,4 +5,4 @@ contract test {
}
}
// ----
-// ParserError: (100-109): Expected primary expression. \ No newline at end of file
+// ParserError: (100-109): Expected string end-quote.
diff --git a/test/libsolidity/syntaxTests/string/string_unterminated.sol b/test/libsolidity/syntaxTests/string/string_unterminated.sol
index 3291781e..e893f4b1 100644
--- a/test/libsolidity/syntaxTests/string/string_unterminated.sol
+++ b/test/libsolidity/syntaxTests/string/string_unterminated.sol
@@ -4,4 +4,4 @@ contract test {
}
}
// ----
-// ParserError: (100-112): Expected primary expression. \ No newline at end of file
+// ParserError: (100-112): Expected string end-quote.
diff --git a/test/libsolidity/syntaxTests/string/string_unterminated_no_new_line.sol b/test/libsolidity/syntaxTests/string/string_unterminated_no_new_line.sol
index e7be50d2..b100396b 100644
--- a/test/libsolidity/syntaxTests/string/string_unterminated_no_new_line.sol
+++ b/test/libsolidity/syntaxTests/string/string_unterminated_no_new_line.sol
@@ -1,4 +1,4 @@
contract test {
function f() pure public { "abc\
// ----
-// ParserError: (47-53): Expected primary expression. \ No newline at end of file
+// ParserError: (47-53): Expected string end-quote.
diff --git a/test/libsolidity/syntaxTests/unicode_escape_literals.sol b/test/libsolidity/syntaxTests/unicode_escape_literals.sol
index a340487b..4415d493 100644
--- a/test/libsolidity/syntaxTests/unicode_escape_literals.sol
+++ b/test/libsolidity/syntaxTests/unicode_escape_literals.sol
@@ -28,4 +28,4 @@ contract test {
}
// ----
-// ParserError: (678-681): Expected primary expression.
+// ParserError: (678-681): Invalid escape sequence.
diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp
index d224bdcd..2e70d086 100644
--- a/test/libyul/Common.cpp
+++ b/test/libyul/Common.cpp
@@ -23,24 +23,24 @@
#include <test/Options.h>
-#include <libyul/optimiser/Disambiguator.h>
-
-#include <libsolidity/parsing/Scanner.h>
+#include <liblangutil/SourceReferenceFormatter.h>
-#include <libsolidity/inlineasm/AsmParser.h>
-#include <libsolidity/inlineasm/AsmAnalysis.h>
-#include <libsolidity/inlineasm/AsmPrinter.h>
+#include <libyul/optimiser/Disambiguator.h>
+#include <libyul/AsmParser.h>
+#include <libyul/AsmAnalysis.h>
+#include <libyul/AsmPrinter.h>
-#include <libsolidity/interface/SourceReferenceFormatter.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/Scanner.h>
+#include <liblangutil/ErrorReporter.h>
#include <boost/test/unit_test.hpp>
using namespace std;
-using namespace dev::yul;
+using namespace langutil;
+using namespace yul;
using namespace dev::solidity;
-void dev::yul::test::printErrors(ErrorList const& _errors, Scanner const& _scanner)
+void yul::test::printErrors(ErrorList const& _errors, Scanner const& _scanner)
{
SourceReferenceFormatter formatter(cout, [&](std::string const&) -> Scanner const& { return _scanner; });
@@ -52,18 +52,18 @@ void dev::yul::test::printErrors(ErrorList const& _errors, Scanner const& _scann
}
-pair<shared_ptr<Block>, shared_ptr<assembly::AsmAnalysisInfo>> dev::yul::test::parse(string const& _source, bool _yul)
+pair<shared_ptr<Block>, shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(string const& _source, bool _yul)
{
- auto flavour = _yul ? assembly::AsmFlavour::Yul : assembly::AsmFlavour::Strict;
+ auto flavour = _yul ? yul::AsmFlavour::Yul : yul::AsmFlavour::Strict;
ErrorList errors;
ErrorReporter errorReporter(errors);
auto scanner = make_shared<Scanner>(CharStream(_source), "");
- auto parserResult = assembly::Parser(errorReporter, flavour).parse(scanner, false);
+ auto parserResult = yul::Parser(errorReporter, flavour).parse(scanner, false);
if (parserResult)
{
BOOST_REQUIRE(errorReporter.errors().empty());
- auto analysisInfo = make_shared<assembly::AsmAnalysisInfo>();
- assembly::AsmAnalyzer analyzer(
+ auto analysisInfo = make_shared<yul::AsmAnalysisInfo>();
+ yul::AsmAnalyzer analyzer(
*analysisInfo,
errorReporter,
dev::test::Options::get().evmVersion(),
@@ -83,13 +83,13 @@ pair<shared_ptr<Block>, shared_ptr<assembly::AsmAnalysisInfo>> dev::yul::test::p
return {};
}
-assembly::Block dev::yul::test::disambiguate(string const& _source, bool _yul)
+yul::Block yul::test::disambiguate(string const& _source, bool _yul)
{
auto result = parse(_source, _yul);
return boost::get<Block>(Disambiguator(*result.second, {})(*result.first));
}
-string dev::yul::test::format(string const& _source, bool _yul)
+string yul::test::format(string const& _source, bool _yul)
{
- return assembly::AsmPrinter(_yul)(*parse(_source, _yul).first);
+ return yul::AsmPrinter(_yul)(*parse(_source, _yul).first);
}
diff --git a/test/libyul/Common.h b/test/libyul/Common.h
index ee191494..a1c64ca5 100644
--- a/test/libyul/Common.h
+++ b/test/libyul/Common.h
@@ -21,35 +21,34 @@
#pragma once
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libyul/AsmData.h>
#include <string>
#include <vector>
#include <memory>
-namespace dev
-{
-namespace solidity
+namespace langutil
{
class Scanner;
class Error;
using ErrorList = std::vector<std::shared_ptr<Error const>>;
-namespace assembly
+}
+
+namespace yul
{
struct AsmAnalysisInfo;
}
-}
+
namespace yul
{
namespace test
{
-void printErrors(solidity::ErrorList const& _errors, solidity::Scanner const& _scanner);
-std::pair<std::shared_ptr<solidity::assembly::Block>, std::shared_ptr<solidity::assembly::AsmAnalysisInfo>>
+void printErrors(langutil::ErrorList const& _errors, langutil::Scanner const& _scanner);
+std::pair<std::shared_ptr<Block>, std::shared_ptr<AsmAnalysisInfo>>
parse(std::string const& _source, bool _yul = true);
-solidity::assembly::Block disambiguate(std::string const& _source, bool _yul = true);
+Block disambiguate(std::string const& _source, bool _yul = true);
std::string format(std::string const& _source, bool _yul = true);
}
}
-}
diff --git a/test/libyul/Inliner.cpp b/test/libyul/Inliner.cpp
index 66810298..631cda08 100644
--- a/test/libyul/Inliner.cpp
+++ b/test/libyul/Inliner.cpp
@@ -26,8 +26,7 @@
#include <libyul/optimiser/FullInliner.h>
#include <libyul/optimiser/FunctionHoister.h>
#include <libyul/optimiser/FunctionGrouper.h>
-
-#include <libsolidity/inlineasm/AsmPrinter.h>
+#include <libyul/AsmPrinter.h>
#include <boost/test/unit_test.hpp>
@@ -36,8 +35,8 @@
using namespace std;
using namespace dev;
-using namespace dev::yul;
-using namespace dev::yul::test;
+using namespace yul;
+using namespace yul::test;
using namespace dev::solidity;
namespace
diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp
index 3f329d28..6f946362 100644
--- a/test/libyul/Parser.cpp
+++ b/test/libyul/Parser.cpp
@@ -23,11 +23,11 @@
#include <test/libsolidity/ErrorCheck.h>
-#include <libsolidity/inlineasm/AsmParser.h>
-#include <libsolidity/inlineasm/AsmAnalysis.h>
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
-#include <libsolidity/parsing/Scanner.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <libyul/AsmParser.h>
+#include <libyul/AsmAnalysis.h>
+#include <libyul/AsmAnalysisInfo.h>
+#include <liblangutil/Scanner.h>
+#include <liblangutil/ErrorReporter.h>
#include <boost/optional.hpp>
#include <boost/algorithm/string/replace.hpp>
@@ -36,10 +36,10 @@
#include <memory>
using namespace std;
+using namespace dev;
+using namespace langutil;
-namespace dev
-{
-namespace solidity
+namespace yul
{
namespace test
{
@@ -52,16 +52,16 @@ bool parse(string const& _source, ErrorReporter& errorReporter)
try
{
auto scanner = make_shared<Scanner>(CharStream(_source));
- auto parserResult = assembly::Parser(errorReporter, assembly::AsmFlavour::Yul).parse(scanner, false);
+ auto parserResult = yul::Parser(errorReporter, yul::AsmFlavour::Yul).parse(scanner, false);
if (parserResult)
{
- assembly::AsmAnalysisInfo analysisInfo;
- return (assembly::AsmAnalyzer(
+ yul::AsmAnalysisInfo analysisInfo;
+ return (yul::AsmAnalyzer(
analysisInfo,
errorReporter,
dev::test::Options::get().evmVersion(),
boost::none,
- assembly::AsmFlavour::Yul
+ yul::AsmFlavour::Yul
)).analyze(*parserResult);
}
}
@@ -116,7 +116,7 @@ do \
{ \
Error err = expectError((text), false); \
BOOST_CHECK(err.type() == (Error::Type::typ)); \
- BOOST_CHECK(searchErrorMessage(err, (substring))); \
+ BOOST_CHECK(dev::solidity::searchErrorMessage(err, (substring))); \
} while(0)
BOOST_AUTO_TEST_SUITE(YulParser)
@@ -302,5 +302,4 @@ BOOST_AUTO_TEST_CASE(if_statement_invalid)
BOOST_AUTO_TEST_SUITE_END()
}
-}
} // end namespaces
diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp
index 03cd6446..c857d8a5 100644
--- a/test/libyul/YulOptimizerTest.cpp
+++ b/test/libyul/YulOptimizerTest.cpp
@@ -31,6 +31,7 @@
#include <libyul/optimiser/FunctionHoister.h>
#include <libyul/optimiser/ExpressionInliner.h>
#include <libyul/optimiser/FullInliner.h>
+#include <libyul/optimiser/ForLoopInitRewriter.h>
#include <libyul/optimiser/MainFunction.h>
#include <libyul/optimiser/Rematerialiser.h>
#include <libyul/optimiser/ExpressionSimplifier.h>
@@ -39,13 +40,13 @@
#include <libyul/optimiser/SSATransform.h>
#include <libyul/optimiser/RedundantAssignEliminator.h>
#include <libyul/optimiser/Suite.h>
+#include <libyul/AsmPrinter.h>
+#include <libyul/AsmParser.h>
+#include <libyul/AsmAnalysis.h>
+#include <liblangutil/SourceReferenceFormatter.h>
-#include <libsolidity/parsing/Scanner.h>
-#include <libsolidity/inlineasm/AsmPrinter.h>
-#include <libsolidity/inlineasm/AsmParser.h>
-#include <libsolidity/inlineasm/AsmAnalysis.h>
-#include <libsolidity/interface/SourceReferenceFormatter.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <liblangutil/ErrorReporter.h>
+#include <liblangutil/Scanner.h>
#include <boost/test/unit_test.hpp>
#include <boost/algorithm/string.hpp>
@@ -53,8 +54,9 @@
#include <fstream>
using namespace dev;
-using namespace dev::yul;
-using namespace dev::yul::test;
+using namespace langutil;
+using namespace yul;
+using namespace yul::test;
using namespace dev::solidity;
using namespace dev::solidity::test;
using namespace std;
@@ -90,9 +92,9 @@ YulOptimizerTest::YulOptimizerTest(string const& _filename)
bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool const _formatted)
{
- assembly::AsmPrinter printer{m_yul};
+ yul::AsmPrinter printer{m_yul};
shared_ptr<Block> ast;
- shared_ptr<assembly::AsmAnalysisInfo> analysisInfo;
+ shared_ptr<yul::AsmAnalysisInfo> analysisInfo;
if (!parse(_stream, _linePrefix, _formatted))
return false;
@@ -108,6 +110,11 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con
disambiguate();
VarDeclPropagator{}(*m_ast);
}
+ else if (m_optimizerStep == "forLoopInitRewriter")
+ {
+ disambiguate();
+ ForLoopInitRewriter{}(*m_ast);
+ }
else if (m_optimizerStep == "commonSubexpressionEliminator")
{
disambiguate();
@@ -249,19 +256,19 @@ void YulOptimizerTest::printIndented(ostream& _stream, string const& _output, st
bool YulOptimizerTest::parse(ostream& _stream, string const& _linePrefix, bool const _formatted)
{
- assembly::AsmFlavour flavour = m_yul ? assembly::AsmFlavour::Yul : assembly::AsmFlavour::Strict;
+ yul::AsmFlavour flavour = m_yul ? yul::AsmFlavour::Yul : yul::AsmFlavour::Strict;
ErrorList errors;
ErrorReporter errorReporter(errors);
shared_ptr<Scanner> scanner = make_shared<Scanner>(CharStream(m_source), "");
- m_ast = assembly::Parser(errorReporter, flavour).parse(scanner, false);
+ m_ast = yul::Parser(errorReporter, flavour).parse(scanner, false);
if (!m_ast || !errorReporter.errors().empty())
{
FormattedScope(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << endl;
printErrors(_stream, errorReporter.errors(), *scanner);
return false;
}
- m_analysisInfo = make_shared<assembly::AsmAnalysisInfo>();
- assembly::AsmAnalyzer analyzer(
+ m_analysisInfo = make_shared<yul::AsmAnalysisInfo>();
+ yul::AsmAnalyzer analyzer(
*m_analysisInfo,
errorReporter,
dev::test::Options::get().evmVersion(),
diff --git a/test/libyul/YulOptimizerTest.h b/test/libyul/YulOptimizerTest.h
index 7db17ceb..90026e24 100644
--- a/test/libyul/YulOptimizerTest.h
+++ b/test/libyul/YulOptimizerTest.h
@@ -17,28 +17,27 @@
#pragma once
-#include <test/libsolidity/TestCase.h>
+#include <test/TestCase.h>
-
-namespace dev
-{
-namespace solidity
+namespace langutil
{
class Scanner;
class Error;
using ErrorList = std::vector<std::shared_ptr<Error const>>;
-namespace assembly
+}
+
+namespace yul
{
struct AsmAnalysisInfo;
struct Block;
}
-}
+
namespace yul
{
namespace test
{
-class YulOptimizerTest: public solidity::test::TestCase
+class YulOptimizerTest: public dev::solidity::test::TestCase
{
public:
static std::unique_ptr<TestCase> create(std::string const& _filename)
@@ -58,18 +57,17 @@ private:
bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted);
void disambiguate();
- static void printErrors(std::ostream& _stream, solidity::ErrorList const& _errors, solidity::Scanner const& _scanner);
+ static void printErrors(std::ostream& _stream, langutil::ErrorList const& _errors, langutil::Scanner const& _scanner);
std::string m_source;
bool m_yul = false;
std::string m_optimizerStep;
std::string m_expectation;
- std::shared_ptr<solidity::assembly::Block> m_ast;
- std::shared_ptr<solidity::assembly::AsmAnalysisInfo> m_analysisInfo;
+ std::shared_ptr<Block> m_ast;
+ std::shared_ptr<AsmAnalysisInfo> m_analysisInfo;
std::string m_obtainedResult;
};
}
}
-}
diff --git a/test/libyul/yulOptimizerTests/forLoopInitRewriter/complex_pre.yul b/test/libyul/yulOptimizerTests/forLoopInitRewriter/complex_pre.yul
new file mode 100644
index 00000000..3ca00f55
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/forLoopInitRewriter/complex_pre.yul
@@ -0,0 +1,23 @@
+{
+ let random := 42
+ for { let a := 1
+ let b := 1 } iszero(eq(a, 10)) { a := add(a, b) } {
+ a := add(a, 1)
+ }
+}
+// ----
+// forLoopInitRewriter
+// {
+// let random := 42
+// let a := 1
+// let b := 1
+// for {
+// }
+// iszero(eq(a, 10))
+// {
+// a := add(a, b)
+// }
+// {
+// a := add(a, 1)
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/forLoopInitRewriter/empty_pre.yul b/test/libyul/yulOptimizerTests/forLoopInitRewriter/empty_pre.yul
new file mode 100644
index 00000000..05aceb52
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/forLoopInitRewriter/empty_pre.yul
@@ -0,0 +1,20 @@
+{
+ let a := 1
+ for {} iszero(eq(a, 10)) { a := add(a, 1) } {
+ a := add(a, 1)
+ }
+}
+// ----
+// forLoopInitRewriter
+// {
+// let a := 1
+// for {
+// }
+// iszero(eq(a, 10))
+// {
+// a := add(a, 1)
+// }
+// {
+// a := add(a, 1)
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/forLoopInitRewriter/simple.yul b/test/libyul/yulOptimizerTests/forLoopInitRewriter/simple.yul
new file mode 100644
index 00000000..565b7725
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/forLoopInitRewriter/simple.yul
@@ -0,0 +1,21 @@
+{
+ let random := 42
+ for { let a := 1 } iszero(eq(a, 10)) { a := add(a, 1) } {
+ a := add(a, 1)
+ }
+}
+// ----
+// forLoopInitRewriter
+// {
+// let random := 42
+// let a := 1
+// for {
+// }
+// iszero(eq(a, 10))
+// {
+// a := add(a, 1)
+// }
+// {
+// a := add(a, 1)
+// }
+// }
diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt
index 19a1d958..736212fc 100644
--- a/test/tools/CMakeLists.txt
+++ b/test/tools/CMakeLists.txt
@@ -4,7 +4,7 @@ target_link_libraries(solfuzzer PRIVATE libsolc evmasm ${Boost_PROGRAM_OPTIONS_L
add_executable(yulopti yulopti.cpp)
target_link_libraries(yulopti PRIVATE solidity ${Boost_PROGRAM_OPTIONS_LIBRARIES} ${Boost_SYSTEM_LIBRARIES})
-add_executable(isoltest isoltest.cpp ../Options.cpp ../Common.cpp ../libsolidity/TestCase.cpp ../libsolidity/SyntaxTest.cpp
+add_executable(isoltest isoltest.cpp ../Options.cpp ../Common.cpp ../TestCase.cpp ../libsolidity/SyntaxTest.cpp
../libsolidity/AnalysisFramework.cpp ../libsolidity/SolidityExecutionFramework.cpp ../ExecutionFramework.cpp
- ../RPCSession.cpp ../libsolidity/ASTJSONTest.cpp ../libyul/YulOptimizerTest.cpp)
+ ../RPCSession.cpp ../libsolidity/ASTJSONTest.cpp ../libsolidity/SMTCheckerJSONTest.cpp ../libyul/YulOptimizerTest.cpp)
target_link_libraries(isoltest PRIVATE libsolc solidity evmasm ${Boost_PROGRAM_OPTIONS_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
diff --git a/test/tools/isoltest.cpp b/test/tools/isoltest.cpp
index 1b6fd54a..f8e2dc58 100644
--- a/test/tools/isoltest.cpp
+++ b/test/tools/isoltest.cpp
@@ -21,6 +21,7 @@
#include <test/libsolidity/AnalysisFramework.h>
#include <test/libsolidity/SyntaxTest.h>
#include <test/libsolidity/ASTJSONTest.h>
+#include <test/libsolidity/SMTCheckerJSONTest.h>
#include <test/libyul/YulOptimizerTest.h>
#include <boost/algorithm/string.hpp>
@@ -412,6 +413,17 @@ Allowed options)",
global_stats += *stats;
else
return 1;
+
+ if (auto stats = runTestSuite(
+ "SMT Checker JSON",
+ testPath / "libsolidity",
+ "smtCheckerTestsJSON",
+ SMTCheckerTest::create,
+ formatted
+ ))
+ global_stats += *stats;
+ else
+ return 1;
}
cout << endl << "Summary: ";
diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp
index 348c5f4a..5a8a5106 100644
--- a/test/tools/yulopti.cpp
+++ b/test/tools/yulopti.cpp
@@ -19,15 +19,15 @@
*/
#include <libdevcore/CommonIO.h>
-#include <libsolidity/inlineasm/AsmAnalysis.h>
-#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
-#include <libsolidity/parsing/Scanner.h>
+#include <liblangutil/ErrorReporter.h>
+#include <liblangutil/Scanner.h>
+#include <libyul/AsmAnalysis.h>
+#include <libyul/AsmAnalysisInfo.h>
#include <libsolidity/parsing/Parser.h>
-#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/inlineasm/AsmParser.h>
-#include <libsolidity/inlineasm/AsmPrinter.h>
-#include <libsolidity/interface/SourceReferenceFormatter.h>
-#include <libsolidity/interface/ErrorReporter.h>
+#include <libyul/AsmData.h>
+#include <libyul/AsmParser.h>
+#include <libyul/AsmPrinter.h>
+#include <liblangutil/SourceReferenceFormatter.h>
#include <libyul/optimiser/BlockFlattener.h>
#include <libyul/optimiser/Disambiguator.h>
@@ -38,6 +38,7 @@
#include <libyul/optimiser/FunctionHoister.h>
#include <libyul/optimiser/ExpressionInliner.h>
#include <libyul/optimiser/FullInliner.h>
+#include <libyul/optimiser/ForLoopInitRewriter.h>
#include <libyul/optimiser/MainFunction.h>
#include <libyul/optimiser/Rematerialiser.h>
#include <libyul/optimiser/ExpressionSimplifier.h>
@@ -57,9 +58,9 @@
using namespace std;
using namespace dev;
+using namespace langutil;
using namespace dev::solidity;
-using namespace dev::solidity::assembly;
-using namespace dev::yul;
+using namespace yul;
namespace po = boost::program_options;
@@ -81,14 +82,14 @@ public:
{
ErrorReporter errorReporter(m_errors);
shared_ptr<Scanner> scanner = make_shared<Scanner>(CharStream(_input), "");
- m_ast = assembly::Parser(errorReporter, assembly::AsmFlavour::Strict).parse(scanner, false);
+ m_ast = yul::Parser(errorReporter, yul::AsmFlavour::Strict).parse(scanner, false);
if (!m_ast || !errorReporter.errors().empty())
{
cout << "Error parsing source." << endl;
printErrors(*scanner);
return false;
}
- m_analysisInfo = make_shared<assembly::AsmAnalysisInfo>();
+ m_analysisInfo = make_shared<yul::AsmAnalysisInfo>();
AsmAnalyzer analyzer(
*m_analysisInfo,
errorReporter,
@@ -116,14 +117,14 @@ public:
return;
if (!disambiguated)
{
- *m_ast = boost::get<assembly::Block>(Disambiguator(*m_analysisInfo)(*m_ast));
+ *m_ast = boost::get<yul::Block>(Disambiguator(*m_analysisInfo)(*m_ast));
m_analysisInfo.reset();
m_nameDispenser = make_shared<NameDispenser>(*m_ast);
disambiguated = true;
}
cout << "(q)quit/(f)flatten/(c)se/propagate var(d)ecls/(x)plit/(j)oin/(g)rouper/(h)oister/" << endl;
cout << " (e)xpr inline/(i)nline/(s)implify/(u)nusedprune/ss(a) transform/" << endl;
- cout << " (r)edundant assign elim./re(m)aterializer? ";
+ cout << " (r)edundant assign elim./re(m)aterializer/f(o)r-loop-pre-rewriter? ";
cout.flush();
int option = readStandardInputChar();
cout << ' ' << char(option) << endl;
@@ -134,6 +135,9 @@ public:
case 'f':
BlockFlattener{}(*m_ast);
break;
+ case 'o':
+ ForLoopInitRewriter{}(*m_ast);
+ break;
case 'c':
(CommonSubexpressionEliminator{})(*m_ast);
break;
@@ -182,7 +186,7 @@ public:
private:
ErrorList m_errors;
- shared_ptr<assembly::Block> m_ast;
+ shared_ptr<yul::Block> m_ast;
shared_ptr<AsmAnalysisInfo> m_analysisInfo;
shared_ptr<NameDispenser> m_nameDispenser;
};