2021-06-07 10:31:05 +00:00
/*
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/>.
*/
// SPDX-License-Identifier: GPL-3.0
2021-06-07 10:33:04 +00:00
# include <solc/CommandLineParser.h>
2021-10-11 11:48:03 +00:00
# include <solc/Exceptions.h>
2021-06-07 10:31:05 +00:00
# include <libyul/optimiser/Suite.h>
2021-10-11 11:48:03 +00:00
2021-06-07 10:31:05 +00:00
# include <liblangutil/EVMVersion.h>
# include <boost/algorithm/string.hpp>
# include <range/v3/view/transform.hpp>
2021-08-24 08:37:26 +00:00
# include <range/v3/view/filter.hpp>
# include <range/v3/range/conversion.hpp>
2021-06-07 10:31:05 +00:00
using namespace std ;
using namespace solidity : : langutil ;
namespace po = boost : : program_options ;
namespace solidity : : frontend
{
static string const g_strAllowPaths = " allow-paths " ;
static string const g_strBasePath = " base-path " ;
2021-08-20 17:17:44 +00:00
static string const g_strIncludePath = " include-path " ;
2021-06-07 10:31:05 +00:00
static string const g_strAssemble = " assemble " ;
static string const g_strCombinedJson = " combined-json " ;
static string const g_strErrorRecovery = " error-recovery " ;
static string const g_strEVM = " evm " ;
static string const g_strEVMVersion = " evm-version " ;
2022-11-22 12:05:20 +00:00
static string const g_strEOFVersion = " experimental-eof-version " ;
2022-03-09 15:02:31 +00:00
static string const g_strViaIR = " via-ir " ;
2021-06-07 10:31:05 +00:00
static string const g_strExperimentalViaIR = " experimental-via-ir " ;
static string const g_strGas = " gas " ;
static string const g_strHelp = " help " ;
static string const g_strImportAst = " import-ast " ;
static string const g_strInputFile = " input-file " ;
static string const g_strYul = " yul " ;
static string const g_strYulDialect = " yul-dialect " ;
2021-09-13 12:17:05 +00:00
static string const g_strDebugInfo = " debug-info " ;
2021-06-07 10:31:05 +00:00
static string const g_strIPFS = " ipfs " ;
static string const g_strLicense = " license " ;
static string const g_strLibraries = " libraries " ;
static string const g_strLink = " link " ;
2021-12-13 13:53:40 +00:00
static string const g_strLSP = " lsp " ;
2021-06-07 10:31:05 +00:00
static string const g_strMachine = " machine " ;
2022-07-11 22:50:32 +00:00
static string const g_strNoCBORMetadata = " no-cbor-metadata " ;
2021-06-07 10:31:05 +00:00
static string const g_strMetadataHash = " metadata-hash " ;
static string const g_strMetadataLiteral = " metadata-literal " ;
static string const g_strModelCheckerContracts = " model-checker-contracts " ;
2021-07-15 15:39:01 +00:00
static string const g_strModelCheckerDivModNoSlacks = " model-checker-div-mod-no-slacks " ;
2021-06-07 10:31:05 +00:00
static string const g_strModelCheckerEngine = " model-checker-engine " ;
2021-10-12 09:12:18 +00:00
static string const g_strModelCheckerExtCalls = " model-checker-ext-calls " ;
2021-10-06 09:51:22 +00:00
static string const g_strModelCheckerInvariants = " model-checker-invariants " ;
2023-02-09 16:07:13 +00:00
static string const g_strModelCheckerShowProvedSafe = " model-checker-show-proved-safe " ;
2021-07-02 12:43:20 +00:00
static string const g_strModelCheckerShowUnproved = " model-checker-show-unproved " ;
2023-03-06 13:19:58 +00:00
static string const g_strModelCheckerShowUnsupported = " model-checker-show-unsupported " ;
2021-05-19 15:35:19 +00:00
static string const g_strModelCheckerSolvers = " model-checker-solvers " ;
2021-06-07 10:31:05 +00:00
static string const g_strModelCheckerTargets = " model-checker-targets " ;
static string const g_strModelCheckerTimeout = " model-checker-timeout " ;
2023-02-23 18:22:46 +00:00
static string const g_strModelCheckerBMCLoopIterations = " model-checker-bmc-loop-iterations " ;
2021-06-07 10:31:05 +00:00
static string const g_strNone = " none " ;
static string const g_strNoOptimizeYul = " no-optimize-yul " ;
static string const g_strOptimize = " optimize " ;
static string const g_strOptimizeRuns = " optimize-runs " ;
static string const g_strOptimizeYul = " optimize-yul " ;
static string const g_strYulOptimizations = " yul-optimizations " ;
static string const g_strOutputDir = " output-dir " ;
static string const g_strOverwrite = " overwrite " ;
static string const g_strRevertStrings = " revert-strings " ;
static string const g_strStopAfter = " stop-after " ;
static string const g_strParsing = " parsing " ;
/// Possible arguments to for --revert-strings
static set < string > const g_revertStringsArgs
{
revertStringsToString ( RevertStrings : : Default ) ,
revertStringsToString ( RevertStrings : : Strip ) ,
revertStringsToString ( RevertStrings : : Debug ) ,
revertStringsToString ( RevertStrings : : VerboseDebug )
} ;
static string const g_strSources = " sources " ;
static string const g_strSourceList = " sourceList " ;
static string const g_strStandardJSON = " standard-json " ;
static string const g_strStrictAssembly = " strict-assembly " ;
static string const g_strSwarm = " swarm " ;
static string const g_strPrettyJson = " pretty-json " ;
2021-07-07 11:18:24 +00:00
static string const g_strJsonIndent = " json-indent " ;
2021-06-07 10:31:05 +00:00
static string const g_strVersion = " version " ;
static string const g_strIgnoreMissingFiles = " ignore-missing " ;
static string const g_strColor = " color " ;
static string const g_strNoColor = " no-color " ;
static string const g_strErrorIds = " error-codes " ;
/// Possible arguments to for --machine
static set < string > const g_machineArgs
{
2023-02-22 15:32:29 +00:00
g_strEVM
2021-06-07 10:31:05 +00:00
} ;
/// Possible arguments to for --yul-dialect
static set < string > const g_yulDialectArgs
{
2023-02-22 15:32:29 +00:00
g_strEVM
2021-06-07 10:31:05 +00:00
} ;
/// Possible arguments to for --metadata-hash
static set < string > const g_metadataHashArgs
{
g_strIPFS ,
g_strSwarm ,
g_strNone
} ;
2021-10-04 14:35:59 +00:00
static map < InputMode , string > const g_inputModeName = {
2021-10-11 11:48:03 +00:00
{ InputMode : : Help , " help " } ,
{ InputMode : : License , " license " } ,
{ InputMode : : Version , " version " } ,
2021-10-04 14:35:59 +00:00
{ InputMode : : Compiler , " compiler " } ,
{ InputMode : : CompilerWithASTImport , " compiler (AST import) " } ,
{ InputMode : : Assembler , " assembler " } ,
{ InputMode : : StandardJson , " standard JSON " } ,
{ InputMode : : Linker , " linker " } ,
2021-12-13 13:53:40 +00:00
{ InputMode : : LanguageServer , " language server (LSP) " } ,
2021-10-04 14:35:59 +00:00
} ;
2021-10-11 11:48:03 +00:00
void CommandLineParser : : checkMutuallyExclusive ( vector < string > const & _optionNames )
2021-06-07 10:31:05 +00:00
{
2021-06-13 12:28:03 +00:00
if ( countEnabledOptions ( _optionNames ) > 1 )
2021-06-07 10:31:05 +00:00
{
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" The following options are mutually exclusive: " + joinOptionNames ( _optionNames ) + " . " +
" Select at most one. "
) ;
2021-06-07 10:31:05 +00:00
}
}
2021-06-10 14:33:08 +00:00
bool CompilerOutputs : : operator = = ( CompilerOutputs const & _other ) const noexcept
{
2021-09-30 13:51:24 +00:00
for ( bool CompilerOutputs : : * member : componentMap ( ) | ranges : : views : : values )
if ( this - > * member ! = _other . * member )
return false ;
return true ;
}
2021-06-10 14:33:08 +00:00
2021-06-10 13:46:46 +00:00
ostream & operator < < ( ostream & _out , CompilerOutputs const & _selection )
{
vector < string > serializedSelection ;
for ( auto & & [ componentName , component ] : CompilerOutputs : : componentMap ( ) )
if ( _selection . * component )
serializedSelection . push_back ( CompilerOutputs : : componentName ( component ) ) ;
2022-03-07 04:25:35 +00:00
return _out < < util : : joinHumanReadable ( serializedSelection , " , " ) ;
2021-06-10 13:46:46 +00:00
}
2021-09-30 13:51:24 +00:00
string const & CompilerOutputs : : componentName ( bool CompilerOutputs : : * _component )
{
solAssert ( _component , " " ) ;
// NOTE: Linear search is not optimal but it's simpler than getting pointers-to-members to work as map keys.
for ( auto const & [ componentName , component ] : CompilerOutputs : : componentMap ( ) )
if ( component = = _component )
return componentName ;
solAssert ( false , " " ) ;
2021-06-10 14:33:08 +00:00
}
bool CombinedJsonRequests : : operator = = ( CombinedJsonRequests const & _other ) const noexcept
{
2021-09-30 14:33:00 +00:00
for ( bool CombinedJsonRequests : : * member : componentMap ( ) | ranges : : views : : values )
if ( this - > * member ! = _other . * member )
return false ;
return true ;
}
2021-06-10 14:33:08 +00:00
2021-06-10 13:46:46 +00:00
ostream & operator < < ( ostream & _out , CombinedJsonRequests const & _requests )
{
vector < string > serializedRequests ;
for ( auto & & [ componentName , component ] : CombinedJsonRequests : : componentMap ( ) )
if ( _requests . * component )
serializedRequests . push_back ( CombinedJsonRequests : : componentName ( component ) ) ;
2022-03-07 04:25:35 +00:00
return _out < < util : : joinHumanReadable ( serializedRequests , " , " ) ;
2021-06-10 13:46:46 +00:00
}
2021-09-30 14:33:00 +00:00
string const & CombinedJsonRequests : : componentName ( bool CombinedJsonRequests : : * _component )
{
solAssert ( _component , " " ) ;
for ( auto const & [ componentName , component ] : CombinedJsonRequests : : componentMap ( ) )
if ( component = = _component )
return componentName ;
solAssert ( false , " " ) ;
2021-06-10 14:33:08 +00:00
}
bool CommandLineOptions : : operator = = ( CommandLineOptions const & _other ) const noexcept
{
return
input . paths = = _other . input . paths & &
input . remappings = = _other . input . remappings & &
input . addStdin = = _other . input . addStdin & &
input . basePath = = _other . input . basePath & &
2021-08-20 17:17:44 +00:00
input . includePaths = = _other . input . includePaths & &
2021-06-10 14:33:08 +00:00
input . allowedDirectories = = _other . input . allowedDirectories & &
input . ignoreMissingFiles = = _other . input . ignoreMissingFiles & &
input . errorRecovery = = _other . input . errorRecovery & &
output . dir = = _other . output . dir & &
output . overwriteFiles = = _other . output . overwriteFiles & &
output . evmVersion = = _other . output . evmVersion & &
2022-03-09 15:02:31 +00:00
output . viaIR = = _other . output . viaIR & &
2021-06-10 14:33:08 +00:00
output . revertStrings = = _other . output . revertStrings & &
2021-09-13 12:17:05 +00:00
output . debugInfoSelection = = _other . output . debugInfoSelection & &
2021-06-10 14:33:08 +00:00
output . stopAfter = = _other . output . stopAfter & &
2022-11-22 12:05:20 +00:00
output . eofVersion = = _other . output . eofVersion & &
2021-06-10 14:33:08 +00:00
input . mode = = _other . input . mode & &
assembly . targetMachine = = _other . assembly . targetMachine & &
assembly . inputLanguage = = _other . assembly . inputLanguage & &
linker . libraries = = _other . linker . libraries & &
2021-07-07 11:18:24 +00:00
formatting . json = = _other . formatting . json & &
2021-06-10 14:33:08 +00:00
formatting . coloredOutput = = _other . formatting . coloredOutput & &
formatting . withErrorIds = = _other . formatting . withErrorIds & &
compiler . outputs = = _other . compiler . outputs & &
compiler . estimateGas = = _other . compiler . estimateGas & &
compiler . combinedJsonRequests = = _other . compiler . combinedJsonRequests & &
2022-07-11 22:50:32 +00:00
metadata . format = = _other . metadata . format & &
2021-06-10 14:33:08 +00:00
metadata . hash = = _other . metadata . hash & &
metadata . literalSources = = _other . metadata . literalSources & &
2023-05-24 12:22:18 +00:00
optimizer . optimizeEvmasm = = _other . optimizer . optimizeEvmasm & &
optimizer . optimizeYul = = _other . optimizer . optimizeYul & &
2021-06-10 14:33:08 +00:00
optimizer . expectedExecutionsPerDeployment = = _other . optimizer . expectedExecutionsPerDeployment & &
optimizer . yulSteps = = _other . optimizer . yulSteps & &
modelChecker . initialize = = _other . modelChecker . initialize & &
modelChecker . settings = = _other . modelChecker . settings ;
}
2021-08-03 15:11:17 +00:00
OptimiserSettings CommandLineOptions : : optimiserSettings ( ) const
{
OptimiserSettings settings ;
2023-05-23 12:59:54 +00:00
if ( optimizer . optimizeEvmasm )
2021-08-03 15:11:17 +00:00
settings = OptimiserSettings : : standard ( ) ;
else
settings = OptimiserSettings : : minimal ( ) ;
2023-05-23 12:59:54 +00:00
settings . runYulOptimiser = optimizer . optimizeYul ;
if ( optimizer . optimizeYul )
// NOTE: Standard JSON disables optimizeStackAllocation by default when yul optimizer is disabled.
// --optimize --no-optimize-yul on the CLI does not have that effect.
settings . optimizeStackAllocation = true ;
2021-08-03 15:11:17 +00:00
if ( optimizer . expectedExecutionsPerDeployment . has_value ( ) )
settings . expectedExecutionsPerDeployment = optimizer . expectedExecutionsPerDeployment . value ( ) ;
if ( optimizer . yulSteps . has_value ( ) )
2022-08-10 13:57:01 +00:00
{
2022-08-23 09:58:12 +00:00
string const fullSequence = optimizer . yulSteps . value ( ) ;
2022-08-10 13:57:01 +00:00
auto const delimiterPos = fullSequence . find ( " : " ) ;
settings . yulOptimiserSteps = fullSequence . substr ( 0 , delimiterPos ) ;
if ( delimiterPos ! = string : : npos )
settings . yulOptimiserCleanupSteps = fullSequence . substr ( delimiterPos + 1 ) ;
2022-09-12 08:57:02 +00:00
else
solAssert ( settings . yulOptimiserCleanupSteps = = OptimiserSettings : : DefaultYulOptimiserCleanupSteps ) ;
2022-08-10 13:57:01 +00:00
}
2021-08-03 15:11:17 +00:00
return settings ;
}
2021-10-11 11:48:03 +00:00
void CommandLineParser : : parse ( int _argc , char const * const * _argv )
2021-09-16 12:15:17 +00:00
{
2021-10-11 11:48:03 +00:00
parseArgs ( _argc , _argv ) ;
processArgs ( ) ;
2021-09-16 12:15:17 +00:00
}
2021-10-11 11:48:03 +00:00
void CommandLineParser : : parseInputPathsAndRemappings ( )
2021-06-07 10:31:05 +00:00
{
2021-06-17 14:20:32 +00:00
m_options . input . ignoreMissingFiles = ( m_args . count ( g_strIgnoreMissingFiles ) > 0 ) ;
2021-06-13 13:53:16 +00:00
2021-06-17 14:20:32 +00:00
if ( m_args . count ( g_strInputFile ) )
2021-07-23 21:43:10 +00:00
for ( string const & positionalArg : m_args [ g_strInputFile ] . as < vector < string > > ( ) )
2021-06-07 10:31:05 +00:00
{
2021-07-23 21:43:10 +00:00
if ( ImportRemapper : : isRemapping ( positionalArg ) )
2021-06-07 10:31:05 +00:00
{
2021-07-23 21:43:10 +00:00
optional < ImportRemapper : : Remapping > remapping = ImportRemapper : : parseRemapping ( positionalArg ) ;
if ( ! remapping . has_value ( ) )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Invalid remapping: \" " + positionalArg + " \" . " ) ;
2021-06-13 13:53:16 +00:00
2021-07-23 21:43:10 +00:00
if ( m_options . input . mode = = InputMode : : StandardJson )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Import remappings are not accepted on the command line in Standard JSON mode. \n "
" Please put them under 'settings.remappings' in the JSON input. "
) ;
2021-06-07 10:31:05 +00:00
2021-07-23 18:27:50 +00:00
if ( ! remapping - > target . empty ( ) )
{
// If the target is a directory, whitelist it. Otherwise whitelist containing dir.
// NOTE: /a/b/c/ is a directory while /a/b/c is not.
boost : : filesystem : : path remappingDir = remapping - > target ;
if ( remappingDir . filename ( ) ! = " .. " )
// As an exception we'll treat /a/b/c/.. as a directory too. It would be
// unintuitive to whitelist /a/b/c when the target is equivalent to /a/b/.
remappingDir . remove_filename ( ) ;
m_options . input . allowedDirectories . insert ( remappingDir . empty ( ) ? " . " : remappingDir ) ;
}
2021-07-23 21:43:10 +00:00
2022-09-01 08:55:29 +00:00
m_options . input . remappings . emplace_back ( std : : move ( remapping . value ( ) ) ) ;
2021-06-07 10:31:05 +00:00
}
2021-07-23 21:43:10 +00:00
else if ( positionalArg = = " - " )
2021-06-07 10:33:04 +00:00
m_options . input . addStdin = true ;
2021-06-07 10:31:05 +00:00
else
2021-07-23 21:43:10 +00:00
m_options . input . paths . insert ( positionalArg ) ;
2021-06-07 10:31:05 +00:00
}
2021-06-13 13:53:16 +00:00
if ( m_options . input . mode = = InputMode : : StandardJson )
{
if ( m_options . input . paths . size ( ) > 1 | | ( m_options . input . paths . size ( ) = = 1 & & m_options . input . addStdin ) )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Too many input files for -- " + g_strStandardJSON + " . \n "
" Please either specify a single file name or provide its content on standard input. "
) ;
2021-06-13 13:53:16 +00:00
else if ( m_options . input . paths . size ( ) = = 0 )
// Standard JSON mode input used to be handled separately and zero files meant "read from stdin".
// Keep it working that way for backwards-compatibility.
m_options . input . addStdin = true ;
}
else if ( m_options . input . paths . size ( ) = = 0 & & ! m_options . input . addStdin )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" No input files given. If you wish to use the standard input please specify \" - \" explicitly. "
) ;
2021-06-07 10:31:05 +00:00
}
2021-10-11 11:48:03 +00:00
void CommandLineParser : : parseLibraryOption ( string const & _input )
2021-06-07 10:31:05 +00:00
{
namespace fs = boost : : filesystem ;
string data = _input ;
try
{
if ( fs : : is_regular_file ( _input ) )
2022-03-07 04:25:35 +00:00
data = util : : readFileAsString ( _input ) ;
2021-06-07 10:31:05 +00:00
}
catch ( fs : : filesystem_error const & )
{
// Thrown e.g. if path is too long.
}
2022-03-07 04:25:35 +00:00
catch ( util : : FileNotFound const & )
2021-06-07 10:31:05 +00:00
{
// Should not happen if `fs::is_regular_file` is correct.
}
2022-03-07 04:25:35 +00:00
catch ( util : : NotAFile const & )
2021-06-07 10:31:05 +00:00
{
// Should not happen if `fs::is_regular_file` is correct.
}
vector < string > libraries ;
boost : : split ( libraries , data , boost : : is_space ( ) | | boost : : is_any_of ( " , " ) , boost : : token_compress_on ) ;
for ( string const & lib : libraries )
if ( ! lib . empty ( ) )
{
//search for equal sign or last colon in string as our binaries output placeholders in the form of file=Name or file:Name
//so we need to search for `=` or `:` in the string
auto separator = lib . rfind ( ' = ' ) ;
bool isSeparatorEqualSign = true ;
if ( separator = = string : : npos )
{
separator = lib . rfind ( ' : ' ) ;
if ( separator = = string : : npos )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Equal sign separator missing in library address specifier \" " + lib + " \" "
) ;
2021-06-07 10:31:05 +00:00
else
isSeparatorEqualSign = false ; // separator is colon
}
else
if ( lib . rfind ( ' = ' ) ! = lib . find ( ' = ' ) )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Only one equal sign \" = \" is allowed in the address string \" " + lib + " \" . "
) ;
2021-06-07 10:31:05 +00:00
string libName ( lib . begin ( ) , lib . begin ( ) + static_cast < ptrdiff_t > ( separator ) ) ;
boost : : trim ( libName ) ;
2021-06-07 10:33:04 +00:00
if ( m_options . linker . libraries . count ( libName ) )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Address specified more than once for library \" " + libName + " \" . "
) ;
2021-06-07 10:31:05 +00:00
string addrString ( lib . begin ( ) + static_cast < ptrdiff_t > ( separator ) + 1 , lib . end ( ) ) ;
boost : : trim ( addrString ) ;
if ( addrString . empty ( ) )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Empty address provided for library \" " + libName + " \" . \n "
" Note that there should not be any whitespace after the " +
( isSeparatorEqualSign ? " equal sign " : " colon " ) + " . "
) ;
2021-06-07 10:31:05 +00:00
if ( addrString . substr ( 0 , 2 ) = = " 0x " )
addrString = addrString . substr ( 2 ) ;
else
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" The address " + addrString + " is not prefixed with \" 0x \" . \n "
" Note that the address must be prefixed with \" 0x \" . "
) ;
2021-06-07 10:31:05 +00:00
if ( addrString . length ( ) ! = 40 )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Invalid length for address for library \" " + libName + " \" : " +
to_string ( addrString . length ( ) ) + " instead of 40 characters. "
) ;
2022-03-07 04:25:35 +00:00
if ( ! util : : passesAddressChecksum ( addrString , false ) )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Invalid checksum on address for library \" " + libName + " \" : " + addrString + " \n "
2022-03-07 04:25:35 +00:00
" The correct checksum is " + util : : getChecksummedAddress ( addrString )
2021-10-11 11:48:03 +00:00
) ;
2022-03-07 04:25:35 +00:00
bytes binAddr = util : : fromHex ( addrString ) ;
util : : h160 address ( binAddr , util : : h160 : : AlignRight ) ;
if ( binAddr . size ( ) > 20 | | address = = util : : h160 ( ) )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Invalid address for library \" " + libName + " \" : " + addrString
) ;
2021-06-07 10:33:04 +00:00
m_options . linker . libraries [ libName ] = address ;
2021-06-07 10:31:05 +00:00
}
}
2021-10-11 11:48:03 +00:00
void CommandLineParser : : parseOutputSelection ( )
2021-10-04 14:35:59 +00:00
{
static auto outputSupported = [ ] ( InputMode _mode , string_view _outputName )
{
2021-11-03 16:01:48 +00:00
static set < string > const compilerModeOutputs = (
2021-10-04 14:35:59 +00:00
CompilerOutputs : : componentMap ( ) |
ranges : : views : : keys |
2021-11-03 16:01:48 +00:00
ranges : : to < set > ( )
2023-02-22 15:32:29 +00:00
) ;
2021-09-30 18:38:28 +00:00
static set < string > const assemblerModeOutputs = {
CompilerOutputs : : componentName ( & CompilerOutputs : : asm_ ) ,
CompilerOutputs : : componentName ( & CompilerOutputs : : binary ) ,
2023-05-02 13:34:12 +00:00
CompilerOutputs : : componentName ( & CompilerOutputs : : irOptimized ) ,
CompilerOutputs : : componentName ( & CompilerOutputs : : astCompactJson ) ,
2021-09-30 18:38:28 +00:00
} ;
2021-10-04 14:35:59 +00:00
switch ( _mode )
{
2021-10-11 11:03:51 +00:00
case InputMode : : Help :
case InputMode : : License :
case InputMode : : Version :
2021-12-13 13:53:40 +00:00
case InputMode : : LanguageServer :
2021-10-11 11:03:51 +00:00
solAssert ( false ) ;
2021-10-04 14:35:59 +00:00
case InputMode : : Compiler :
case InputMode : : CompilerWithASTImport :
2022-03-07 04:25:35 +00:00
return util : : contains ( compilerModeOutputs , _outputName ) ;
2021-10-04 14:35:59 +00:00
case InputMode : : Assembler :
2022-03-07 04:25:35 +00:00
return util : : contains ( assemblerModeOutputs , _outputName ) ;
2021-10-04 14:35:59 +00:00
case InputMode : : StandardJson :
case InputMode : : Linker :
return false ;
}
solAssert ( false , " " ) ;
} ;
for ( auto & & [ optionName , outputComponent ] : CompilerOutputs : : componentMap ( ) )
m_options . compiler . outputs . * outputComponent = ( m_args . count ( optionName ) > 0 ) ;
2021-09-30 18:38:28 +00:00
if ( m_options . input . mode = = InputMode : : Assembler & & m_options . compiler . outputs = = CompilerOutputs { } )
{
// In assembly mode keep the default outputs enabled for backwards-compatibility.
// TODO: Remove this (must be done in a breaking release).
m_options . compiler . outputs . asm_ = true ;
m_options . compiler . outputs . binary = true ;
m_options . compiler . outputs . irOptimized = true ;
}
2021-10-04 14:35:59 +00:00
vector < string > unsupportedOutputs ;
for ( auto & & [ optionName , outputComponent ] : CompilerOutputs : : componentMap ( ) )
if ( m_options . compiler . outputs . * outputComponent & & ! outputSupported ( m_options . input . mode , optionName ) )
unsupportedOutputs . push_back ( optionName ) ;
if ( ! unsupportedOutputs . empty ( ) )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" The following outputs are not supported in " + g_inputModeName . at ( m_options . input . mode ) + " mode: " +
joinOptionNames ( unsupportedOutputs ) + " . "
) ;
2022-11-22 12:05:20 +00:00
// TODO: restrict EOF version to correct EVM version.
2021-10-04 14:35:59 +00:00
}
2022-11-22 12:05:20 +00:00
po : : options_description CommandLineParser : : optionsDescription ( bool _forHelp )
2021-06-07 10:31:05 +00:00
{
// Declare the supported options.
po : : options_description desc ( ( R " (solc, the Solidity commandline compiler.
This program comes with ABSOLUTELY NO WARRANTY . This is free software , and you
are welcome to redistribute it under certain conditions . See ' solc - - ) " + g_strLicense + R " ( '
for details .
Usage : solc [ options ] [ input_file . . . ]
2023-05-24 07:23:53 +00:00
Compiles the given Solidity input files ( or the standard input if " - " is
used as a file name ) and outputs the components specified in the options
2021-06-07 10:31:05 +00:00
at standard output or in files in the output directory , if specified .
Imports are automatically read from the filesystem , but it is also possible to
remap paths using the context : prefix = path syntax .
Example :
2021-09-30 13:51:24 +00:00
solc - - ) " + CompilerOutputs::componentName(&CompilerOutputs::binary) + R " ( - o / tmp / solcoutput dapp - bin = / usr / local / lib / dapp - bin contract . sol
2021-06-07 10:31:05 +00:00
General Information ) " ).c_str(),
po : : options_description : : m_default_line_length ,
po : : options_description : : m_default_line_length - 23
) ;
desc . add_options ( )
2021-06-17 14:20:32 +00:00
( g_strHelp . c_str ( ) , " Show help message and exit. " )
( g_strVersion . c_str ( ) , " Show version and exit. " )
2021-06-07 10:31:05 +00:00
( g_strLicense . c_str ( ) , " Show licensing information and exit. " )
;
po : : options_description inputOptions ( " Input Options " ) ;
inputOptions . add_options ( )
(
2021-06-17 14:20:32 +00:00
g_strBasePath . c_str ( ) ,
2021-06-07 10:31:05 +00:00
po : : value < string > ( ) - > value_name ( " path " ) ,
" Use the given path as the root of the source tree instead of the root of the filesystem. "
)
2021-08-20 17:17:44 +00:00
(
g_strIncludePath . c_str ( ) ,
po : : value < vector < string > > ( ) - > value_name ( " path " ) ,
" Make an additional source directory available to the default import callback. "
" Use this option if you want to import contracts whose location is not fixed in relation "
" to your main source tree, e.g. third-party libraries installed using a package manager. "
" Can be used multiple times. "
" Can only be used if base path has a non-empty value. "
)
2021-06-07 10:31:05 +00:00
(
2021-06-17 14:20:32 +00:00
g_strAllowPaths . c_str ( ) ,
2021-06-07 10:31:05 +00:00
po : : value < string > ( ) - > value_name ( " path(s) " ) ,
" Allow a given path for imports. A list of paths can be supplied by separating them with a comma. "
)
(
2021-06-17 14:20:32 +00:00
g_strIgnoreMissingFiles . c_str ( ) ,
2021-06-07 10:31:05 +00:00
" Ignore missing files. "
)
(
2021-06-17 14:20:32 +00:00
g_strErrorRecovery . c_str ( ) ,
2021-06-07 10:31:05 +00:00
" Enables additional parser error recovery. "
)
;
desc . add ( inputOptions ) ;
po : : options_description outputOptions ( " Output Options " ) ;
outputOptions . add_options ( )
(
2021-06-17 14:20:32 +00:00
( g_strOutputDir + " ,o " ) . c_str ( ) ,
2021-06-07 10:31:05 +00:00
po : : value < string > ( ) - > value_name ( " path " ) ,
2022-07-21 15:27:24 +00:00
" If given, creates one file per output component and contract/file at the specified directory. "
2021-06-07 10:31:05 +00:00
)
(
g_strOverwrite . c_str ( ) ,
" Overwrite existing files (used together with -o). "
)
(
g_strEVMVersion . c_str ( ) ,
po : : value < string > ( ) - > value_name ( " version " ) - > default_value ( EVMVersion { } . name ( ) ) ,
" Select desired EVM version. Either homestead, tangerineWhistle, spuriousDragon, "
2023-04-09 14:19:55 +00:00
" byzantium, constantinople, petersburg, istanbul, berlin, london, paris or shanghai. "
2021-06-07 10:31:05 +00:00
)
2022-11-22 12:05:20 +00:00
;
if ( ! _forHelp ) // Note: We intentionally keep this undocumented for now.
outputOptions . add_options ( )
(
g_strEOFVersion . c_str ( ) ,
// Declared as uint64_t, since uint8_t will be parsed as character by boost.
po : : value < uint64_t > ( ) - > value_name ( " version " ) - > implicit_value ( 1 ) ,
" Select desired EOF version. Currently the only valid value is 1. "
" If not specified, legacy non-EOF bytecode will be generated. "
)
;
outputOptions . add_options ( )
2021-06-07 10:31:05 +00:00
(
g_strExperimentalViaIR . c_str ( ) ,
2022-03-09 15:02:31 +00:00
" Deprecated synonym of --via-ir. "
)
(
g_strViaIR . c_str ( ) ,
" Turn on compilation mode via the IR. "
2021-06-07 10:31:05 +00:00
)
(
g_strRevertStrings . c_str ( ) ,
2022-03-07 04:25:35 +00:00
po : : value < string > ( ) - > value_name ( util : : joinHumanReadable ( g_revertStringsArgs , " , " ) ) ,
2021-06-07 10:31:05 +00:00
" Strip revert (and require) reason strings or add additional debugging information. "
)
2021-09-13 12:17:05 +00:00
(
g_strDebugInfo . c_str ( ) ,
2022-03-07 04:25:35 +00:00
po : : value < string > ( ) - > default_value ( util : : toString ( DebugInfoSelection : : Default ( ) ) ) ,
2021-09-13 12:17:05 +00:00
( " Debug info components to be included in the produced EVM assembly and Yul code. "
" Value can be all, none or a comma-separated list containing one or more of the "
2022-03-07 04:25:35 +00:00
" following components: " + util : : joinHumanReadable ( DebugInfoSelection : : componentMap ( ) | ranges : : views : : keys ) + " . " ) . c_str ( )
2021-09-13 12:17:05 +00:00
)
2021-06-07 10:31:05 +00:00
(
g_strStopAfter . c_str ( ) ,
po : : value < string > ( ) - > value_name ( " stage " ) ,
" Stop execution after the given compiler stage. Valid options: \" parsing \" . "
)
;
desc . add ( outputOptions ) ;
po : : options_description alternativeInputModes ( " Alternative Input Modes " ) ;
alternativeInputModes . add_options ( )
(
2021-06-17 14:20:32 +00:00
g_strStandardJSON . c_str ( ) ,
2021-06-07 10:31:05 +00:00
" Switch to Standard JSON input / output mode, ignoring all options. "
" It reads from standard input, if no input file was given, otherwise it reads from the provided input file. The result will be written to standard output. "
)
(
2021-06-17 14:20:32 +00:00
g_strLink . c_str ( ) ,
( " Switch to linker mode, ignoring all options apart from -- " + g_strLibraries + " "
2021-06-07 10:31:05 +00:00
" and modify binaries in place. " ) . c_str ( )
)
(
2021-06-17 14:20:32 +00:00
g_strAssemble . c_str ( ) ,
2023-05-23 12:59:54 +00:00
" Switch to assembly mode and assume input is assembly. "
2021-06-07 10:31:05 +00:00
)
(
2021-06-17 14:20:32 +00:00
g_strYul . c_str ( ) ,
2023-05-23 12:59:54 +00:00
" Switch to Yul mode and assume input is Yul. "
2021-06-07 10:31:05 +00:00
)
(
2021-06-17 14:20:32 +00:00
g_strStrictAssembly . c_str ( ) ,
2023-05-23 12:59:54 +00:00
" Switch to strict assembly mode and assume input is strict assembly. "
2021-06-07 10:31:05 +00:00
)
(
2021-06-17 14:20:32 +00:00
g_strImportAst . c_str ( ) ,
2021-06-07 10:31:05 +00:00
( " Import ASTs to be compiled, assumes input holds the AST in compact JSON format. "
2021-06-17 14:20:32 +00:00
" Supported Inputs is the output of the -- " + g_strStandardJSON + " or the one produced by "
2021-09-30 14:33:00 +00:00
" -- " + g_strCombinedJson + " " + CombinedJsonRequests : : componentName ( & CombinedJsonRequests : : ast ) ) . c_str ( )
2021-06-07 10:31:05 +00:00
)
2021-12-13 13:53:40 +00:00
(
g_strLSP . c_str ( ) ,
" Switch to language server mode ( \" LSP \" ). Allows the compiler to be used as an analysis backend "
" for your favourite IDE. "
)
2021-06-07 10:31:05 +00:00
;
desc . add ( alternativeInputModes ) ;
po : : options_description assemblyModeOptions ( " Assembly Mode Options " ) ;
assemblyModeOptions . add_options ( )
(
2021-06-17 14:20:32 +00:00
g_strMachine . c_str ( ) ,
2022-03-07 04:25:35 +00:00
po : : value < string > ( ) - > value_name ( util : : joinHumanReadable ( g_machineArgs , " , " ) ) ,
2021-06-07 10:31:05 +00:00
" Target machine in assembly or Yul mode. "
)
(
g_strYulDialect . c_str ( ) ,
2022-03-07 04:25:35 +00:00
po : : value < string > ( ) - > value_name ( util : : joinHumanReadable ( g_yulDialectArgs , " , " ) ) ,
2021-06-07 10:31:05 +00:00
" Input dialect to use in assembly or yul mode. "
)
;
desc . add ( assemblyModeOptions ) ;
po : : options_description linkerModeOptions ( " Linker Mode Options " ) ;
linkerModeOptions . add_options ( )
(
2021-06-17 14:20:32 +00:00
g_strLibraries . c_str ( ) ,
2021-06-07 10:31:05 +00:00
po : : value < vector < string > > ( ) - > value_name ( " libs " ) ,
" Direct string or file containing library addresses. Syntax: "
" <libraryName>=<address> [, or whitespace] ... \n "
" Address is interpreted as a hex string prefixed by 0x. "
)
;
desc . add ( linkerModeOptions ) ;
po : : options_description outputFormatting ( " Output Formatting " ) ;
outputFormatting . add_options ( )
(
2021-06-17 14:20:32 +00:00
g_strPrettyJson . c_str ( ) ,
2021-07-07 11:18:24 +00:00
" Output JSON in pretty format. "
)
(
g_strJsonIndent . c_str ( ) ,
po : : value < uint32_t > ( ) - > value_name ( " N " ) - > default_value ( util : : JsonFormat : : defaultIndent ) ,
" Indent pretty-printed JSON with N spaces. Enables '--pretty-json' automatically. "
2021-06-07 10:31:05 +00:00
)
(
2021-06-17 14:20:32 +00:00
g_strColor . c_str ( ) ,
2021-06-07 10:31:05 +00:00
" Force colored output. "
)
(
2021-06-17 14:20:32 +00:00
g_strNoColor . c_str ( ) ,
2021-06-07 10:31:05 +00:00
" Explicitly disable colored output, disabling terminal auto-detection. "
)
(
2021-06-17 14:20:32 +00:00
g_strErrorIds . c_str ( ) ,
2021-06-07 10:31:05 +00:00
" Output error codes. "
)
;
desc . add ( outputFormatting ) ;
po : : options_description outputComponents ( " Output Components " ) ;
outputComponents . add_options ( )
2021-09-30 13:51:24 +00:00
( CompilerOutputs : : componentName ( & CompilerOutputs : : astCompactJson ) . c_str ( ) , " AST of all source files in a compact JSON format. " )
( CompilerOutputs : : componentName ( & CompilerOutputs : : asm_ ) . c_str ( ) , " EVM assembly of the contracts. " )
( CompilerOutputs : : componentName ( & CompilerOutputs : : asmJson ) . c_str ( ) , " EVM assembly of the contracts in JSON format. " )
( CompilerOutputs : : componentName ( & CompilerOutputs : : opcodes ) . c_str ( ) , " Opcodes of the contracts. " )
( CompilerOutputs : : componentName ( & CompilerOutputs : : binary ) . c_str ( ) , " Binary of the contracts in hex. " )
( CompilerOutputs : : componentName ( & CompilerOutputs : : binaryRuntime ) . c_str ( ) , " Binary of the runtime part of the contracts in hex. " )
( CompilerOutputs : : componentName ( & CompilerOutputs : : abi ) . c_str ( ) , " ABI specification of the contracts. " )
2022-03-09 15:02:31 +00:00
( CompilerOutputs : : componentName ( & CompilerOutputs : : ir ) . c_str ( ) , " Intermediate Representation (IR) of all contracts. " )
2023-05-02 13:34:12 +00:00
( CompilerOutputs : : componentName ( & CompilerOutputs : : irAstJson ) . c_str ( ) , " AST of Intermediate Representation (IR) of all contracts in a compact JSON format. " )
( CompilerOutputs : : componentName ( & CompilerOutputs : : irOptimized ) . c_str ( ) , " Optimized Intermediate Representation (IR) of all contracts. " )
( CompilerOutputs : : componentName ( & CompilerOutputs : : irOptimizedAstJson ) . c_str ( ) , " AST of optimized Intermediate Representation (IR) of all contracts in a compact JSON format. " )
2021-09-30 13:51:24 +00:00
( CompilerOutputs : : componentName ( & CompilerOutputs : : signatureHashes ) . c_str ( ) , " Function signature hashes of the contracts. " )
( CompilerOutputs : : componentName ( & CompilerOutputs : : natspecUser ) . c_str ( ) , " Natspec user documentation of all contracts. " )
( CompilerOutputs : : componentName ( & CompilerOutputs : : natspecDev ) . c_str ( ) , " Natspec developer documentation of all contracts. " )
2022-07-21 15:27:24 +00:00
( CompilerOutputs : : componentName ( & CompilerOutputs : : metadata ) . c_str ( ) , " Combined Metadata JSON whose IPFS hash is stored on-chain. " )
2021-09-30 13:51:24 +00:00
( CompilerOutputs : : componentName ( & CompilerOutputs : : storageLayout ) . c_str ( ) , " Slots, offsets and types of the contract's state variables. " )
2021-06-07 10:31:05 +00:00
;
desc . add ( outputComponents ) ;
po : : options_description extraOutput ( " Extra Output " ) ;
extraOutput . add_options ( )
(
2021-06-17 14:20:32 +00:00
g_strGas . c_str ( ) ,
2021-06-07 10:31:05 +00:00
" Print an estimate of the maximal gas usage for each function. "
)
(
2021-06-17 14:20:32 +00:00
g_strCombinedJson . c_str ( ) ,
2022-03-07 04:25:35 +00:00
po : : value < string > ( ) - > value_name ( util : : joinHumanReadable ( CombinedJsonRequests : : componentMap ( ) | ranges : : views : : keys , " , " ) ) ,
2021-06-07 10:31:05 +00:00
" Output a single json document containing the specified information. "
)
;
desc . add ( extraOutput ) ;
po : : options_description metadataOptions ( " Metadata Options " ) ;
metadataOptions . add_options ( )
2022-07-11 22:50:32 +00:00
(
g_strNoCBORMetadata . c_str ( ) ,
" Do not append CBOR metadata to the end of the bytecode. "
)
2021-06-07 10:31:05 +00:00
(
2021-06-17 14:20:32 +00:00
g_strMetadataHash . c_str ( ) ,
2022-03-07 04:25:35 +00:00
po : : value < string > ( ) - > value_name ( util : : joinHumanReadable ( g_metadataHashArgs , " , " ) ) ,
2021-06-07 10:31:05 +00:00
" Choose hash method for the bytecode metadata or disable it. "
)
(
2021-06-17 14:20:32 +00:00
g_strMetadataLiteral . c_str ( ) ,
2021-06-07 10:31:05 +00:00
" Store referenced sources as literal data in the metadata output. "
)
;
desc . add ( metadataOptions ) ;
po : : options_description optimizerOptions ( " Optimizer Options " ) ;
optimizerOptions . add_options ( )
(
2021-06-17 14:20:32 +00:00
g_strOptimize . c_str ( ) ,
2023-05-23 12:59:54 +00:00
" Enable optimizer. "
2021-06-07 10:31:05 +00:00
)
(
2021-06-17 14:20:32 +00:00
g_strOptimizeRuns . c_str ( ) ,
2021-06-07 10:31:05 +00:00
// TODO: The type in OptimiserSettings is size_t but we only accept values up to 2**32-1
// on the CLI and in Standard JSON. We should just switch to uint32_t everywhere.
po : : value < unsigned > ( ) - > value_name ( " n " ) - > default_value ( static_cast < unsigned > ( OptimiserSettings { } . expectedExecutionsPerDeployment ) ) ,
2021-09-22 22:54:05 +00:00
" The number of runs specifies roughly how often each opcode of the deployed code will be executed across the lifetime of the contract. "
2021-06-07 10:31:05 +00:00
" Lower values will optimize more for initial deployment cost, higher values will optimize more for high-frequency usage. "
)
(
g_strOptimizeYul . c_str ( ) ,
2023-05-23 12:59:54 +00:00
( " Enable Yul optimizer (independently of the EVM assembly optimizer). "
" The general -- " + g_strOptimize + " option automatically enables this unless -- " +
g_strNoOptimizeYul + " is specified. " ) . c_str ( )
2021-06-07 10:31:05 +00:00
)
(
g_strNoOptimizeYul . c_str ( ) ,
2023-05-23 12:59:54 +00:00
" Disable Yul optimizer (independently of the EVM assembly optimizer). "
2021-06-07 10:31:05 +00:00
)
(
g_strYulOptimizations . c_str ( ) ,
po : : value < string > ( ) - > value_name ( " steps " ) ,
2023-05-23 12:59:54 +00:00
" Forces Yul optimizer to use the specified sequence of optimization steps instead of the built-in one. "
2021-06-07 10:31:05 +00:00
)
;
desc . add ( optimizerOptions ) ;
po : : options_description smtCheckerOptions ( " Model Checker Options " ) ;
smtCheckerOptions . add_options ( )
(
g_strModelCheckerContracts . c_str ( ) ,
po : : value < string > ( ) - > value_name ( " default,<source>:<contract> " ) - > default_value ( " default " ) ,
" Select which contracts should be analyzed using the form <source>:<contract>. "
" Multiple pairs <source>:<contract> can be selected at the same time, separated by a comma "
" and no spaces. "
)
2021-07-15 15:39:01 +00:00
(
g_strModelCheckerDivModNoSlacks . c_str ( ) ,
" Encode division and modulo operations with their precise operators "
" instead of multiplication with slack variables. "
)
2021-06-07 10:31:05 +00:00
(
g_strModelCheckerEngine . c_str ( ) ,
po : : value < string > ( ) - > value_name ( " all,bmc,chc,none " ) - > default_value ( " none " ) ,
" Select model checker engine. "
)
2021-10-12 09:12:18 +00:00
(
g_strModelCheckerExtCalls . c_str ( ) ,
po : : value < string > ( ) - > value_name ( " untrusted,trusted " ) - > default_value ( " untrusted " ) ,
" Select whether to assume (trusted) that external calls always invoke "
" the code given by the type of the contract, if that code is available. "
)
2021-10-06 09:51:22 +00:00
(
g_strModelCheckerInvariants . c_str ( ) ,
po : : value < string > ( ) - > value_name ( " default,all,contract,reentrancy " ) - > default_value ( " default " ) ,
" Select whether to report inferred contract inductive invariants. "
" Multiple types of invariants can be selected at the same time, separated by a comma and no spaces. "
" By default no invariants are reported. "
)
2023-02-09 16:07:13 +00:00
(
g_strModelCheckerShowProvedSafe . c_str ( ) ,
" Show all targets that were proved safe separately. "
)
2021-07-02 12:43:20 +00:00
(
g_strModelCheckerShowUnproved . c_str ( ) ,
2021-08-11 08:54:03 +00:00
" Show all unproved targets separately. "
2021-07-02 12:43:20 +00:00
)
2023-03-06 13:19:58 +00:00
(
g_strModelCheckerShowUnsupported . c_str ( ) ,
" Show all unsupported language features separately. "
)
2021-05-19 15:35:19 +00:00
(
g_strModelCheckerSolvers . c_str ( ) ,
2022-05-15 15:45:43 +00:00
po : : value < string > ( ) - > value_name ( " cvc4,eld,z3,smtlib2 " ) - > default_value ( " z3 " ) ,
2021-05-19 15:35:19 +00:00
" Select model checker solvers. "
)
2021-06-07 10:31:05 +00:00
(
g_strModelCheckerTargets . c_str ( ) ,
2021-07-07 10:31:09 +00:00
po : : value < string > ( ) - > value_name ( " default,all,constantCondition,underflow,overflow,divByZero,balance,assert,popEmptyArray,outOfBounds " ) - > default_value ( " default " ) ,
2023-02-23 18:22:46 +00:00
" Select model checker verification targets. "
2021-07-07 10:31:09 +00:00
" Multiple targets can be selected at the same time, separated by a comma and no spaces. "
" By default all targets except underflow and overflow are selected. "
2021-06-07 10:31:05 +00:00
)
(
g_strModelCheckerTimeout . c_str ( ) ,
po : : value < unsigned > ( ) - > value_name ( " ms " ) ,
2023-02-23 18:22:46 +00:00
" Set model checker timeout per query in milliseconds. "
" The default is a deterministic resource limit. "
2021-06-07 10:31:05 +00:00
" A timeout of 0 means no resource/time restrictions for any query. "
)
2023-02-23 18:22:46 +00:00
(
g_strModelCheckerBMCLoopIterations . c_str ( ) ,
po : : value < unsigned > ( ) ,
" Set loop unrolling depth for BMC engine. "
" Default is 1. "
)
2021-06-07 10:31:05 +00:00
;
desc . add ( smtCheckerOptions ) ;
2021-09-16 12:15:17 +00:00
desc . add_options ( ) ( g_strInputFile . c_str ( ) , po : : value < vector < string > > ( ) , " input file " ) ;
return desc ;
}
2021-06-07 10:31:05 +00:00
2021-09-16 12:15:17 +00:00
po : : positional_options_description CommandLineParser : : positionalOptionsDescription ( )
{
2021-06-07 10:31:05 +00:00
// All positional options should be interpreted as input files
po : : positional_options_description filesPositions ;
2021-06-17 14:20:32 +00:00
filesPositions . add ( g_strInputFile . c_str ( ) , - 1 ) ;
2021-09-16 12:15:17 +00:00
return filesPositions ;
}
2021-10-11 11:48:03 +00:00
void CommandLineParser : : parseArgs ( int _argc , char const * const * _argv )
2021-09-16 12:15:17 +00:00
{
po : : options_description allOptions = optionsDescription ( ) ;
po : : positional_options_description filesPositions = positionalOptionsDescription ( ) ;
2021-06-07 10:31:05 +00:00
// parse the compiler arguments
try
{
po : : command_line_parser cmdLineParser ( _argc , _argv ) ;
cmdLineParser . style ( po : : command_line_style : : default_style & ( ~ po : : command_line_style : : allow_guessing ) ) ;
cmdLineParser . options ( allOptions ) . positional ( filesPositions ) ;
po : : store ( cmdLineParser . run ( ) , m_args ) ;
}
catch ( po : : error const & _exception )
{
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , _exception . what ( ) ) ;
2021-06-07 10:31:05 +00:00
}
2021-09-16 12:15:17 +00:00
po : : notify ( m_args ) ;
}
2021-10-11 11:48:03 +00:00
void CommandLineParser : : processArgs ( )
2021-09-16 12:15:17 +00:00
{
2021-10-11 11:48:03 +00:00
checkMutuallyExclusive ( {
2021-10-11 11:03:51 +00:00
g_strHelp ,
g_strLicense ,
g_strVersion ,
2021-09-16 12:21:56 +00:00
g_strStandardJSON ,
g_strLink ,
g_strAssemble ,
g_strStrictAssembly ,
g_strYul ,
g_strImportAst ,
2022-11-02 04:58:45 +00:00
g_strLSP ,
2021-10-11 11:48:03 +00:00
} ) ;
2021-09-16 12:21:56 +00:00
2021-10-11 11:03:51 +00:00
if ( m_args . count ( g_strHelp ) > 0 )
m_options . input . mode = InputMode : : Help ;
else if ( m_args . count ( g_strLicense ) > 0 )
m_options . input . mode = InputMode : : License ;
else if ( m_args . count ( g_strVersion ) > 0 )
m_options . input . mode = InputMode : : Version ;
else if ( m_args . count ( g_strStandardJSON ) > 0 )
2021-09-16 12:21:56 +00:00
m_options . input . mode = InputMode : : StandardJson ;
2021-12-13 13:53:40 +00:00
else if ( m_args . count ( g_strLSP ) )
m_options . input . mode = InputMode : : LanguageServer ;
2021-09-16 12:21:56 +00:00
else if ( m_args . count ( g_strAssemble ) > 0 | | m_args . count ( g_strStrictAssembly ) > 0 | | m_args . count ( g_strYul ) > 0 )
m_options . input . mode = InputMode : : Assembler ;
else if ( m_args . count ( g_strLink ) > 0 )
m_options . input . mode = InputMode : : Linker ;
else if ( m_args . count ( g_strImportAst ) > 0 )
m_options . input . mode = InputMode : : CompilerWithASTImport ;
else
m_options . input . mode = InputMode : : Compiler ;
2021-10-11 11:03:51 +00:00
if (
m_options . input . mode = = InputMode : : Help | |
m_options . input . mode = = InputMode : : License | |
m_options . input . mode = = InputMode : : Version
)
2021-10-11 11:48:03 +00:00
return ;
2021-10-11 11:03:51 +00:00
2021-08-31 16:57:09 +00:00
map < string , set < InputMode > > validOptionInputModeCombinations = {
// TODO: This should eventually contain all options.
{ g_strErrorRecovery , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
{ g_strExperimentalViaIR , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
2021-11-01 13:47:30 +00:00
{ g_strViaIR , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
{ g_strMetadataLiteral , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
2022-07-11 22:50:32 +00:00
{ g_strNoCBORMetadata , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
2021-11-01 13:47:30 +00:00
{ g_strMetadataHash , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
2023-02-09 16:07:13 +00:00
{ g_strModelCheckerShowProvedSafe , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
2021-11-01 13:47:30 +00:00
{ g_strModelCheckerShowUnproved , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
2023-03-06 13:19:58 +00:00
{ g_strModelCheckerShowUnsupported , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
2021-11-01 13:47:30 +00:00
{ g_strModelCheckerDivModNoSlacks , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
{ g_strModelCheckerEngine , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
{ g_strModelCheckerInvariants , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
{ g_strModelCheckerSolvers , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
{ g_strModelCheckerTimeout , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
2023-02-23 18:22:46 +00:00
{ g_strModelCheckerBMCLoopIterations , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
2021-11-01 13:47:30 +00:00
{ g_strModelCheckerContracts , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } } ,
{ g_strModelCheckerTargets , { InputMode : : Compiler , InputMode : : CompilerWithASTImport } }
2021-08-31 16:57:09 +00:00
} ;
vector < string > invalidOptionsForCurrentInputMode ;
for ( auto const & [ optionName , inputModes ] : validOptionInputModeCombinations )
{
2021-11-01 13:47:30 +00:00
if (
m_args . count ( optionName ) > 0 & &
inputModes . count ( m_options . input . mode ) = = 0 & &
! m_args [ optionName ] . defaulted ( )
)
2021-08-31 16:57:09 +00:00
invalidOptionsForCurrentInputMode . push_back ( optionName ) ;
}
if ( ! invalidOptionsForCurrentInputMode . empty ( ) )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" The following options are not supported in the current input mode: " +
joinOptionNames ( invalidOptionsForCurrentInputMode )
) ;
2021-09-16 12:21:56 +00:00
2021-12-13 13:53:40 +00:00
if ( m_options . input . mode = = InputMode : : LanguageServer )
return ;
2021-10-11 11:48:03 +00:00
checkMutuallyExclusive ( { g_strColor , g_strNoColor } ) ;
2021-06-07 10:31:05 +00:00
2021-11-03 16:01:48 +00:00
array < string , 9 > const conflictingWithStopAfter {
2021-09-30 13:51:24 +00:00
CompilerOutputs : : componentName ( & CompilerOutputs : : binary ) ,
CompilerOutputs : : componentName ( & CompilerOutputs : : ir ) ,
2023-05-02 13:34:12 +00:00
CompilerOutputs : : componentName ( & CompilerOutputs : : irAstJson ) ,
2021-09-30 13:51:24 +00:00
CompilerOutputs : : componentName ( & CompilerOutputs : : irOptimized ) ,
2023-05-02 13:34:12 +00:00
CompilerOutputs : : componentName ( & CompilerOutputs : : irOptimizedAstJson ) ,
2021-06-17 14:20:32 +00:00
g_strGas ,
2021-09-30 13:51:24 +00:00
CompilerOutputs : : componentName ( & CompilerOutputs : : asm_ ) ,
CompilerOutputs : : componentName ( & CompilerOutputs : : asmJson ) ,
CompilerOutputs : : componentName ( & CompilerOutputs : : opcodes ) ,
2021-06-07 10:31:05 +00:00
} ;
for ( auto & option : conflictingWithStopAfter )
2021-10-11 11:48:03 +00:00
checkMutuallyExclusive ( { g_strStopAfter , option } ) ;
2021-06-07 10:31:05 +00:00
2021-09-16 12:21:56 +00:00
if (
m_options . input . mode ! = InputMode : : Compiler & &
m_options . input . mode ! = InputMode : : CompilerWithASTImport & &
m_options . input . mode ! = InputMode : : Assembler
)
{
if ( ! m_args [ g_strOptimizeRuns ] . defaulted ( ) )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Option -- " + g_strOptimizeRuns + " is only valid in compiler and assembler modes. "
) ;
2021-09-16 12:21:56 +00:00
for ( string const & option : { g_strOptimize , g_strNoOptimizeYul , g_strOptimizeYul , g_strYulOptimizations } )
if ( m_args . count ( option ) > 0 )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Option -- " + option + " is only valid in compiler and assembler modes. "
) ;
2021-09-13 12:17:05 +00:00
if ( ! m_args [ g_strDebugInfo ] . defaulted ( ) )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Option -- " + g_strDebugInfo + " is only valid in compiler and assembler modes. "
) ;
2021-09-16 12:21:56 +00:00
}
2021-06-17 14:20:32 +00:00
if ( m_args . count ( g_strColor ) > 0 )
2021-06-07 10:33:04 +00:00
m_options . formatting . coloredOutput = true ;
2021-06-17 14:20:32 +00:00
else if ( m_args . count ( g_strNoColor ) > 0 )
2021-06-07 10:33:04 +00:00
m_options . formatting . coloredOutput = false ;
2021-06-07 10:31:05 +00:00
2021-06-17 14:20:32 +00:00
m_options . formatting . withErrorIds = m_args . count ( g_strErrorIds ) ;
2021-06-07 10:31:05 +00:00
if ( m_args . count ( g_strRevertStrings ) )
{
string revertStringsString = m_args [ g_strRevertStrings ] . as < string > ( ) ;
2022-11-02 04:58:45 +00:00
optional < RevertStrings > revertStrings = revertStringsFromString ( revertStringsString ) ;
2021-06-07 10:31:05 +00:00
if ( ! revertStrings )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Invalid option for -- " + g_strRevertStrings + " : " + revertStringsString
) ;
2021-06-07 10:31:05 +00:00
if ( * revertStrings = = RevertStrings : : VerboseDebug )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Only \" default \" , \" strip \" and \" debug \" are implemented for -- " + g_strRevertStrings + " for now. "
) ;
2021-06-07 10:33:04 +00:00
m_options . output . revertStrings = * revertStrings ;
2021-06-07 10:31:05 +00:00
}
2021-09-13 12:17:05 +00:00
if ( ! m_args [ g_strDebugInfo ] . defaulted ( ) )
{
string optionValue = m_args [ g_strDebugInfo ] . as < string > ( ) ;
m_options . output . debugInfoSelection = DebugInfoSelection : : fromString ( optionValue ) ;
if ( ! m_options . output . debugInfoSelection . has_value ( ) )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Invalid value for -- " + g_strDebugInfo + " option: " + optionValue ) ;
2021-09-13 12:17:05 +00:00
if ( m_options . output . debugInfoSelection - > snippet & & ! m_options . output . debugInfoSelection - > location )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " To use 'snippet' with -- " + g_strDebugInfo + " you must select also 'location'. " ) ;
2021-09-13 12:17:05 +00:00
}
2021-10-11 11:48:03 +00:00
parseCombinedJsonOption ( ) ;
2021-06-07 10:31:05 +00:00
2021-06-17 14:20:32 +00:00
if ( m_args . count ( g_strOutputDir ) )
m_options . output . dir = m_args . at ( g_strOutputDir ) . as < string > ( ) ;
2021-06-07 10:33:04 +00:00
m_options . output . overwriteFiles = ( m_args . count ( g_strOverwrite ) > 0 ) ;
2021-07-07 11:18:24 +00:00
if ( m_args . count ( g_strPrettyJson ) > 0 )
{
2022-03-07 04:25:35 +00:00
m_options . formatting . json . format = util : : JsonFormat : : Pretty ;
2021-07-07 11:18:24 +00:00
}
if ( ! m_args [ g_strJsonIndent ] . defaulted ( ) )
{
2022-03-07 04:25:35 +00:00
m_options . formatting . json . format = util : : JsonFormat : : Pretty ;
2021-07-07 11:18:24 +00:00
m_options . formatting . json . indent = m_args [ g_strJsonIndent ] . as < uint32_t > ( ) ;
}
2021-06-07 10:33:04 +00:00
2021-10-11 11:48:03 +00:00
parseOutputSelection ( ) ;
2021-06-17 14:20:32 +00:00
m_options . compiler . estimateGas = ( m_args . count ( g_strGas ) > 0 ) ;
2021-06-07 10:33:04 +00:00
2021-06-17 14:20:32 +00:00
if ( m_args . count ( g_strBasePath ) )
m_options . input . basePath = m_args [ g_strBasePath ] . as < string > ( ) ;
2021-06-07 10:31:05 +00:00
2021-08-20 17:17:44 +00:00
if ( m_args . count ( g_strIncludePath ) > 0 )
{
if ( m_options . input . basePath . empty ( ) )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " -- " + g_strIncludePath + " option requires a non-empty base path. " ) ;
2021-08-20 17:17:44 +00:00
for ( string const & includePath : m_args [ g_strIncludePath ] . as < vector < string > > ( ) )
{
if ( includePath . empty ( ) )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Empty values are not allowed in -- " + g_strIncludePath + " . " ) ;
2021-08-20 17:17:44 +00:00
m_options . input . includePaths . push_back ( includePath ) ;
}
}
2021-06-17 14:20:32 +00:00
if ( m_args . count ( g_strAllowPaths ) )
2021-06-07 10:31:05 +00:00
{
vector < string > paths ;
2021-07-21 17:00:30 +00:00
for ( string const & allowedPath : boost : : split ( paths , m_args [ g_strAllowPaths ] . as < string > ( ) , boost : : is_any_of ( " , " ) ) )
2021-07-23 23:30:17 +00:00
if ( ! allowedPath . empty ( ) )
m_options . input . allowedDirectories . insert ( allowedPath ) ;
2021-06-07 10:31:05 +00:00
}
if ( m_args . count ( g_strStopAfter ) )
{
if ( m_args [ g_strStopAfter ] . as < string > ( ) ! = " parsing " )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Valid options for -- " + g_strStopAfter + " are: \" parsing \" . \n " ) ;
2021-06-07 10:31:05 +00:00
else
2021-06-07 10:33:04 +00:00
m_options . output . stopAfter = CompilerStack : : State : : Parsed ;
2021-06-07 10:31:05 +00:00
}
2021-10-11 11:48:03 +00:00
parseInputPathsAndRemappings ( ) ;
2021-06-07 10:31:05 +00:00
2021-06-13 13:53:16 +00:00
if ( m_options . input . mode = = InputMode : : StandardJson )
2021-10-11 11:48:03 +00:00
return ;
2021-06-13 13:53:16 +00:00
2021-06-17 14:20:32 +00:00
if ( m_args . count ( g_strLibraries ) )
for ( string const & library : m_args [ g_strLibraries ] . as < vector < string > > ( ) )
2021-10-11 11:48:03 +00:00
parseLibraryOption ( library ) ;
2021-06-07 10:31:05 +00:00
2021-08-03 13:50:02 +00:00
if ( m_options . input . mode = = InputMode : : Linker )
2021-10-11 11:48:03 +00:00
return ;
2021-08-03 13:50:02 +00:00
2021-06-07 10:31:05 +00:00
if ( m_args . count ( g_strEVMVersion ) )
{
string versionOptionStr = m_args [ g_strEVMVersion ] . as < string > ( ) ;
2022-11-02 04:58:45 +00:00
optional < langutil : : EVMVersion > versionOption = langutil : : EVMVersion : : fromString ( versionOptionStr ) ;
2021-06-07 10:31:05 +00:00
if ( ! versionOption )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Invalid option for -- " + g_strEVMVersion + " : " + versionOptionStr ) ;
2021-06-07 10:33:04 +00:00
m_options . output . evmVersion = * versionOption ;
2021-06-07 10:31:05 +00:00
}
2022-11-22 12:05:20 +00:00
if ( m_args . count ( g_strEOFVersion ) )
{
// Request as uint64_t, since uint8_t will be parsed as character by boost.
uint64_t versionOption = m_args [ g_strEOFVersion ] . as < uint64_t > ( ) ;
if ( versionOption ! = 1 )
solThrow ( CommandLineValidationError , " Invalid option for -- " + g_strEOFVersion + " : " + to_string ( versionOption ) ) ;
m_options . output . eofVersion = 1 ;
}
2023-05-24 13:40:36 +00:00
if ( m_args . count ( g_strNoOptimizeYul ) > 0 & & m_args . count ( g_strOptimizeYul ) > 0 )
solThrow (
CommandLineValidationError ,
" Options -- " + g_strOptimizeYul + " and -- " + g_strNoOptimizeYul + " cannot be used together. "
) ;
2023-05-24 12:22:18 +00:00
m_options . optimizer . optimizeEvmasm = ( m_args . count ( g_strOptimize ) > 0 ) ;
m_options . optimizer . optimizeYul = (
2023-05-23 12:59:54 +00:00
( m_args . count ( g_strOptimize ) > 0 & & m_args . count ( g_strNoOptimizeYul ) = = 0 ) | |
m_args . count ( g_strOptimizeYul ) > 0
2023-05-24 12:22:18 +00:00
) ;
2021-08-03 14:20:44 +00:00
if ( ! m_args [ g_strOptimizeRuns ] . defaulted ( ) )
m_options . optimizer . expectedExecutionsPerDeployment = m_args . at ( g_strOptimizeRuns ) . as < unsigned > ( ) ;
if ( m_args . count ( g_strYulOptimizations ) )
{
2021-08-03 15:11:17 +00:00
OptimiserSettings optimiserSettings = m_options . optimiserSettings ( ) ;
2021-08-03 14:20:44 +00:00
if ( ! optimiserSettings . runYulOptimiser )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " -- " + g_strYulOptimizations + " is invalid if Yul optimizer is disabled " ) ;
2021-08-03 14:20:44 +00:00
try
{
yul : : OptimiserSuite : : validateSequence ( m_args [ g_strYulOptimizations ] . as < string > ( ) ) ;
}
catch ( yul : : OptimizerException const & _exception )
{
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Invalid optimizer step sequence in -- " + g_strYulOptimizations + " : " + _exception . what ( )
) ;
2021-08-03 14:20:44 +00:00
}
m_options . optimizer . yulSteps = m_args [ g_strYulOptimizations ] . as < string > ( ) ;
}
2021-06-13 12:30:16 +00:00
if ( m_options . input . mode = = InputMode : : Assembler )
2021-06-07 10:31:05 +00:00
{
vector < string > const nonAssemblyModeOptions = {
// TODO: The list is not complete. Add more.
2021-06-17 14:20:32 +00:00
g_strOutputDir ,
g_strGas ,
g_strCombinedJson ,
2021-06-07 10:31:05 +00:00
} ;
if ( countEnabledOptions ( nonAssemblyModeOptions ) > = 1 )
{
auto optionEnabled = [ & ] ( string const & name ) { return m_args . count ( name ) > 0 ; } ;
2021-08-24 08:37:26 +00:00
auto enabledOptions = nonAssemblyModeOptions | ranges : : views : : filter ( optionEnabled ) | ranges : : to_vector ;
2021-06-07 10:31:05 +00:00
2021-10-11 11:48:03 +00:00
string message = " The following options are invalid in assembly mode: " + joinOptionNames ( enabledOptions ) + " . " ;
solThrow ( CommandLineValidationError , message ) ;
2021-06-07 10:31:05 +00:00
}
// switch to assembly mode
2022-03-28 04:27:11 +00:00
using Input = yul : : YulStack : : Language ;
using Machine = yul : : YulStack : : Machine ;
2021-06-17 14:20:32 +00:00
m_options . assembly . inputLanguage = m_args . count ( g_strYul ) ? Input : : Yul : ( m_args . count ( g_strStrictAssembly ) ? Input : : StrictAssembly : Input : : Assembly ) ;
2021-06-07 10:31:05 +00:00
2021-06-17 14:20:32 +00:00
if ( m_args . count ( g_strMachine ) )
2021-06-07 10:31:05 +00:00
{
2021-06-17 14:20:32 +00:00
string machine = m_args [ g_strMachine ] . as < string > ( ) ;
2021-06-07 10:31:05 +00:00
if ( machine = = g_strEVM )
2021-06-07 10:33:04 +00:00
m_options . assembly . targetMachine = Machine : : EVM ;
2021-06-07 10:31:05 +00:00
else
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Invalid option for -- " + g_strMachine + " : " + machine ) ;
2021-06-07 10:31:05 +00:00
}
if ( m_args . count ( g_strYulDialect ) )
{
string dialect = m_args [ g_strYulDialect ] . as < string > ( ) ;
if ( dialect = = g_strEVM )
2021-06-07 10:33:04 +00:00
m_options . assembly . inputLanguage = Input : : StrictAssembly ;
2021-06-07 10:31:05 +00:00
else
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Invalid option for -- " + g_strYulDialect + " : " + dialect ) ;
2021-06-07 10:31:05 +00:00
}
2023-05-24 12:22:18 +00:00
if (
( m_options . optimizer . optimizeEvmasm | | m_options . optimizer . optimizeYul ) & &
m_options . assembly . inputLanguage ! = Input : : StrictAssembly
)
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" Optimizer can only be used for strict assembly. Use -- " + g_strStrictAssembly + " . "
) ;
return ;
2021-06-07 10:31:05 +00:00
}
2021-06-17 14:20:32 +00:00
else if ( countEnabledOptions ( { g_strYulDialect , g_strMachine } ) > = 1 )
2021-10-11 11:48:03 +00:00
solThrow (
CommandLineValidationError ,
" -- " + g_strYulDialect + " and -- " + g_strMachine + " are only valid in assembly mode. "
) ;
2021-06-07 10:31:05 +00:00
2021-06-17 14:20:32 +00:00
if ( m_args . count ( g_strMetadataHash ) )
2021-06-07 10:31:05 +00:00
{
2021-06-17 14:20:32 +00:00
string hashStr = m_args [ g_strMetadataHash ] . as < string > ( ) ;
2021-06-07 10:31:05 +00:00
if ( hashStr = = g_strIPFS )
2021-06-07 10:33:04 +00:00
m_options . metadata . hash = CompilerStack : : MetadataHash : : IPFS ;
2021-06-07 10:31:05 +00:00
else if ( hashStr = = g_strSwarm )
2021-06-07 10:33:04 +00:00
m_options . metadata . hash = CompilerStack : : MetadataHash : : Bzzr1 ;
2021-06-07 10:31:05 +00:00
else if ( hashStr = = g_strNone )
2021-06-07 10:33:04 +00:00
m_options . metadata . hash = CompilerStack : : MetadataHash : : None ;
2021-06-07 10:31:05 +00:00
else
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Invalid option for -- " + g_strMetadataHash + " : " + hashStr ) ;
2021-06-07 10:31:05 +00:00
}
2022-07-11 22:50:32 +00:00
if ( m_args . count ( g_strNoCBORMetadata ) )
{
if (
m_args . count ( g_strMetadataHash ) & &
m_options . metadata . hash ! = CompilerStack : : MetadataHash : : None
)
solThrow (
CommandLineValidationError ,
" Cannot specify a metadata hashing method when -- " +
g_strNoCBORMetadata + " is set. "
) ;
m_options . metadata . format = CompilerStack : : MetadataFormat : : NoMetadata ;
}
2021-06-17 14:20:32 +00:00
if ( m_args . count ( g_strModelCheckerContracts ) )
2021-06-07 10:31:05 +00:00
{
2021-06-17 14:20:32 +00:00
string contractsStr = m_args [ g_strModelCheckerContracts ] . as < string > ( ) ;
2021-06-07 10:31:05 +00:00
optional < ModelCheckerContracts > contracts = ModelCheckerContracts : : fromString ( contractsStr ) ;
if ( ! contracts )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Invalid option for -- " + g_strModelCheckerContracts + " : " + contractsStr ) ;
2022-09-01 08:55:29 +00:00
m_options . modelChecker . settings . contracts = std : : move ( * contracts ) ;
2021-06-07 10:31:05 +00:00
}
2021-07-15 15:39:01 +00:00
if ( m_args . count ( g_strModelCheckerDivModNoSlacks ) )
m_options . modelChecker . settings . divModNoSlacks = true ;
2021-06-17 14:20:32 +00:00
if ( m_args . count ( g_strModelCheckerEngine ) )
2021-06-07 10:31:05 +00:00
{
2021-06-17 14:20:32 +00:00
string engineStr = m_args [ g_strModelCheckerEngine ] . as < string > ( ) ;
2021-06-07 10:31:05 +00:00
optional < ModelCheckerEngine > engine = ModelCheckerEngine : : fromString ( engineStr ) ;
if ( ! engine )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Invalid option for -- " + g_strModelCheckerEngine + " : " + engineStr ) ;
2021-06-07 10:33:04 +00:00
m_options . modelChecker . settings . engine = * engine ;
2021-06-07 10:31:05 +00:00
}
2021-10-12 09:12:18 +00:00
if ( m_args . count ( g_strModelCheckerExtCalls ) )
{
string mode = m_args [ g_strModelCheckerExtCalls ] . as < string > ( ) ;
optional < ModelCheckerExtCalls > extCallsMode = ModelCheckerExtCalls : : fromString ( mode ) ;
if ( ! extCallsMode )
solThrow ( CommandLineValidationError , " Invalid option for -- " + g_strModelCheckerExtCalls + " : " + mode ) ;
m_options . modelChecker . settings . externalCalls = * extCallsMode ;
}
2021-10-06 09:51:22 +00:00
if ( m_args . count ( g_strModelCheckerInvariants ) )
{
string invsStr = m_args [ g_strModelCheckerInvariants ] . as < string > ( ) ;
optional < ModelCheckerInvariants > invs = ModelCheckerInvariants : : fromString ( invsStr ) ;
if ( ! invs )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Invalid option for -- " + g_strModelCheckerInvariants + " : " + invsStr ) ;
2021-10-06 09:51:22 +00:00
m_options . modelChecker . settings . invariants = * invs ;
}
2023-02-09 16:07:13 +00:00
if ( m_args . count ( g_strModelCheckerShowProvedSafe ) )
m_options . modelChecker . settings . showProvedSafe = true ;
2021-07-02 12:43:20 +00:00
if ( m_args . count ( g_strModelCheckerShowUnproved ) )
2021-08-11 08:54:03 +00:00
m_options . modelChecker . settings . showUnproved = true ;
2021-07-02 12:43:20 +00:00
2023-03-06 13:19:58 +00:00
if ( m_args . count ( g_strModelCheckerShowUnsupported ) )
m_options . modelChecker . settings . showUnsupported = true ;
2021-05-19 15:35:19 +00:00
if ( m_args . count ( g_strModelCheckerSolvers ) )
{
string solversStr = m_args [ g_strModelCheckerSolvers ] . as < string > ( ) ;
optional < smtutil : : SMTSolverChoice > solvers = smtutil : : SMTSolverChoice : : fromString ( solversStr ) ;
if ( ! solvers )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Invalid option for -- " + g_strModelCheckerSolvers + " : " + solversStr ) ;
2021-05-19 15:35:19 +00:00
m_options . modelChecker . settings . solvers = * solvers ;
}
2021-06-17 14:20:32 +00:00
if ( m_args . count ( g_strModelCheckerTargets ) )
2021-06-07 10:31:05 +00:00
{
2021-06-17 14:20:32 +00:00
string targetsStr = m_args [ g_strModelCheckerTargets ] . as < string > ( ) ;
2021-06-07 10:31:05 +00:00
optional < ModelCheckerTargets > targets = ModelCheckerTargets : : fromString ( targetsStr ) ;
if ( ! targets )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Invalid option for -- " + g_strModelCheckerTargets + " : " + targetsStr ) ;
2021-06-07 10:33:04 +00:00
m_options . modelChecker . settings . targets = * targets ;
2021-06-07 10:31:05 +00:00
}
2021-06-17 14:20:32 +00:00
if ( m_args . count ( g_strModelCheckerTimeout ) )
m_options . modelChecker . settings . timeout = m_args [ g_strModelCheckerTimeout ] . as < unsigned > ( ) ;
2021-06-07 10:33:04 +00:00
2023-02-23 18:22:46 +00:00
if ( m_args . count ( g_strModelCheckerBMCLoopIterations ) )
{
if ( ! m_options . modelChecker . settings . engine . bmc )
solThrow ( CommandLineValidationError , " BMC loop unrolling requires the BMC engine to be enabled " ) ;
m_options . modelChecker . settings . bmcLoopIterations = m_args [ g_strModelCheckerBMCLoopIterations ] . as < unsigned > ( ) ;
}
2021-06-17 14:20:32 +00:00
m_options . metadata . literalSources = ( m_args . count ( g_strMetadataLiteral ) > 0 ) ;
2021-06-07 10:33:04 +00:00
m_options . modelChecker . initialize =
2021-06-17 14:20:32 +00:00
m_args . count ( g_strModelCheckerContracts ) | |
2021-07-15 15:39:01 +00:00
m_args . count ( g_strModelCheckerDivModNoSlacks ) | |
2021-06-17 14:20:32 +00:00
m_args . count ( g_strModelCheckerEngine ) | |
2021-10-12 09:12:18 +00:00
m_args . count ( g_strModelCheckerExtCalls ) | |
2021-10-06 09:51:22 +00:00
m_args . count ( g_strModelCheckerInvariants ) | |
2023-02-09 16:07:13 +00:00
m_args . count ( g_strModelCheckerShowProvedSafe ) | |
2021-07-02 12:43:20 +00:00
m_args . count ( g_strModelCheckerShowUnproved ) | |
2023-03-06 13:19:58 +00:00
m_args . count ( g_strModelCheckerShowUnsupported ) | |
2021-05-19 15:35:19 +00:00
m_args . count ( g_strModelCheckerSolvers ) | |
2021-06-17 14:20:32 +00:00
m_args . count ( g_strModelCheckerTargets ) | |
m_args . count ( g_strModelCheckerTimeout ) ;
2022-03-09 15:02:31 +00:00
m_options . output . viaIR = ( m_args . count ( g_strExperimentalViaIR ) > 0 | | m_args . count ( g_strViaIR ) > 0 ) ;
2021-06-13 12:30:16 +00:00
if ( m_options . input . mode = = InputMode : : Compiler )
2021-06-17 14:20:32 +00:00
m_options . input . errorRecovery = ( m_args . count ( g_strErrorRecovery ) > 0 ) ;
2021-06-07 10:31:05 +00:00
2021-09-23 15:18:13 +00:00
solAssert ( m_options . input . mode = = InputMode : : Compiler | | m_options . input . mode = = InputMode : : CompilerWithASTImport ) ;
2021-06-07 10:31:05 +00:00
}
2021-10-11 11:48:03 +00:00
void CommandLineParser : : parseCombinedJsonOption ( )
2021-06-07 10:31:05 +00:00
{
2021-06-17 14:20:32 +00:00
if ( ! m_args . count ( g_strCombinedJson ) )
2021-10-11 11:48:03 +00:00
return ;
2021-06-07 10:31:05 +00:00
2021-06-07 10:33:04 +00:00
set < string > requests ;
2021-06-17 14:20:32 +00:00
for ( string const & item : boost : : split ( requests , m_args [ g_strCombinedJson ] . as < string > ( ) , boost : : is_any_of ( " , " ) ) )
2021-09-30 14:33:00 +00:00
if ( CombinedJsonRequests : : componentMap ( ) . count ( item ) = = 0 )
2021-10-11 11:48:03 +00:00
solThrow ( CommandLineValidationError , " Invalid option to -- " + g_strCombinedJson + " : " + item ) ;
2021-06-07 10:31:05 +00:00
2021-06-07 10:33:04 +00:00
m_options . compiler . combinedJsonRequests = CombinedJsonRequests { } ;
2021-09-30 14:33:00 +00:00
for ( auto & & [ componentName , component ] : CombinedJsonRequests : : componentMap ( ) )
m_options . compiler . combinedJsonRequests . value ( ) . * component = ( requests . count ( componentName ) > 0 ) ;
2021-06-07 10:31:05 +00:00
}
2021-06-07 10:33:04 +00:00
size_t CommandLineParser : : countEnabledOptions ( vector < string > const & _optionNames ) const
2021-06-07 10:31:05 +00:00
{
size_t count = 0 ;
for ( string const & _option : _optionNames )
count + = m_args . count ( _option ) ;
return count ;
}
2021-06-07 10:33:04 +00:00
string CommandLineParser : : joinOptionNames ( vector < string > const & _optionNames , string _separator )
2021-06-07 10:31:05 +00:00
{
2022-03-07 04:25:35 +00:00
return util : : joinHumanReadable (
2021-06-07 10:31:05 +00:00
_optionNames | ranges : : views : : transform ( [ ] ( string const & _option ) { return " -- " + _option ; } ) ,
_separator
) ;
}
2021-06-10 15:45:09 +00:00
2021-06-07 10:33:04 +00:00
} // namespace solidity::frontend