Merge branch 'develop' into patch-2

This commit is contained in:
Markus Osterlund / robriks 2023-09-13 15:58:12 -04:00 committed by GitHub
commit c43c3c3a3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
587 changed files with 12601 additions and 11095 deletions

View File

@ -179,47 +179,199 @@ commands:
paths:
- << parameters.install_path >>
defaults:
# --------------------------------------------------------------------------
# Build Templates
# Build Commands
- setup_prerelease_commit_hash: &setup_prerelease_commit_hash
setup_prerelease_commit_hash:
steps:
- run:
name: Store commit hash and prerelease
command: |
if [ "$CIRCLE_BRANCH" = release -o -n "$CIRCLE_TAG" ]; then echo -n > prerelease.txt; else date -u +"nightly.%Y.%-m.%-d" > prerelease.txt; fi
if [[ $CIRCLE_BRANCH == release || -n $CIRCLE_TAG ]]; then
echo -n > prerelease.txt;
else
date -u +"nightly.%Y.%-m.%-d" > prerelease.txt;
fi
echo -n "$CIRCLE_SHA1" > commit_hash.txt
- run_build: &run_build
run_build:
steps:
- run:
name: Build
command: scripts/ci/build.sh
- run_build_ossfuzz: &run_build_ossfuzz
run_build_ossfuzz:
steps:
- run:
name: Build_ossfuzz
command: scripts/ci/build_ossfuzz.sh
- run_proofs: &run_proofs
run_proofs:
steps:
- run:
name: Correctness proofs for optimization rules
command: scripts/run_proofs.sh
- run_soltest: &run_soltest
run_soltest:
steps:
- run:
name: soltest
no_output_timeout: 30m
command: ./.circleci/soltest.sh
command: .circleci/soltest.sh
- run_soltest_all: &run_soltest_all
run_soltest_all:
steps:
- run:
name: soltest_all
no_output_timeout: 30m
command: ./.circleci/soltest_all.sh
command: .circleci/soltest_all.sh
- run_cmdline_tests: &run_cmdline_tests
run_cmdline_tests:
steps:
- run:
name: command line tests
no_output_timeout: 30m
command: .circleci/parallel_cli_tests.py
- run_docs_pragma_min_version: &run_docs_pragma_min_version
run_docs_pragma_min_version:
steps:
- run:
name: docs pragma version check
command: ./scripts/docs_version_pragma_check.sh
command: scripts/docs_version_pragma_check.sh
# --------------------------------------------------------------------------
# Artifact Commands
store_artifacts_solc:
description: Store compiled solc executable as artifact
steps:
- store_artifacts:
path: build/solc/solc
destination: solc
store_artifacts_yul_phaser:
steps:
- store_artifacts:
path: build/tools/yul-phaser
destination: yul-phaser
persist_executables_to_workspace:
description: Persist compiled target executables to workspace
steps:
- persist_to_workspace:
root: build
paths:
- solc/solc
- test/soltest
- test/tools/solfuzzer
persist_executables_to_workspace_osx:
description: Persist compiled target executables to workspace on macOS
steps:
- persist_to_workspace:
root: .
paths:
- build/solc/solc
- build/test/soltest
- build/test/tools/solfuzzer
persist_ossfuzz_executables_to_workspace:
description: Persist compiled OSSFUZZ executables to workspace
steps:
- persist_to_workspace:
root: build
paths:
- test/tools/ossfuzz/abiv2_proto_ossfuzz
- test/tools/ossfuzz/abiv2_isabelle_ossfuzz
- test/tools/ossfuzz/const_opt_ossfuzz
- test/tools/ossfuzz/solc_mutator_ossfuzz
- test/tools/ossfuzz/solc_ossfuzz
- test/tools/ossfuzz/stack_reuse_codegen_ossfuzz
- test/tools/ossfuzz/strictasm_assembly_ossfuzz
- test/tools/ossfuzz/strictasm_diff_ossfuzz
- test/tools/ossfuzz/strictasm_opt_ossfuzz
- test/tools/ossfuzz/yul_proto_diff_ossfuzz
- test/tools/ossfuzz/yul_proto_diff_custom_mutate_ossfuzz
- test/tools/ossfuzz/yul_proto_ossfuzz
- test/tools/ossfuzz/sol_proto_ossfuzz
store_artifacts_test_results:
description: Store test output dir as artifact
steps:
- store_artifacts:
path: test_results/
destination: test_results/
# --------------------------------------------------------------------------
# Complex Build Commands
soltest:
steps:
- checkout
- attach_workspace:
at: build
# NOTE: Different build jobs produce different soltest executables (release/debug,
# clang/gcc, windows/linux/macos, etc.). The executable used by these steps comes from the
# attached workspace and we only see the items added to the workspace by jobs we depend on.
- run_soltest
- store_test_results:
path: test_results/
- store_artifacts_test_results
- matrix_notify_failure_unless_pr
test_lsp:
steps:
- checkout
- attach_workspace:
at: build
- run:
name: Install dependencies
command: pip install --user deepdiff colorama
- run:
name: Executing solc LSP test suite
command: test/lsp.py build/solc/solc --non-interactive
- matrix_notify_failure_unless_pr
build:
steps:
- checkout
- run_build
- store_artifacts_solc
- store_artifacts_yul_phaser
- persist_executables_to_workspace
- matrix_notify_failure_unless_pr
soltest_all:
steps:
- checkout
- attach_workspace:
at: build
- run_soltest_all
- store_test_results:
path: test_results/
- store_artifacts_test_results
- matrix_notify_failure_unless_pr
cmdline_tests:
steps:
- checkout
- attach_workspace:
at: build
- run_cmdline_tests
- store_test_results:
path: test_results/
- store_artifacts_test_results
- matrix_notify_failure_unless_pr
install_dependencies_osx:
steps:
# FIXME: We used to cache dependencies on macOS but now it takes longer than just installing
# them each time. See https://github.com/ethereum/solidity/issues/12925.
- run:
name: Install build dependencies
command: .circleci/osx_install_dependencies.sh
defaults:
# --------------------------------------------------------------------------
# Matrix templates
@ -241,122 +393,6 @@ defaults:
- via-ir-no-optimize
# --------------------------------------------------------------------------
# Artifacts Templates
# compiled solc executable target
- artifacts_solc: &artifacts_solc
path: build/solc/solc
destination: solc
# windows artifacts
- artifact_solc_windows: &artifact_solc_windows
path: upload/
- artifact_yul_phaser: &artifact_yul_phaser
path: build/tools/yul-phaser
destination: yul-phaser
# compiled executable targets
- artifacts_executables: &artifacts_executables
root: build
paths:
- solc/solc
- test/soltest
- test/tools/solfuzzer
# compiled OSSFUZZ targets
- artifacts_executables_ossfuzz: &artifacts_executables_ossfuzz
root: build
paths:
- test/tools/ossfuzz/abiv2_proto_ossfuzz
- test/tools/ossfuzz/abiv2_isabelle_ossfuzz
- test/tools/ossfuzz/const_opt_ossfuzz
- test/tools/ossfuzz/solc_mutator_ossfuzz
- test/tools/ossfuzz/solc_ossfuzz
- test/tools/ossfuzz/stack_reuse_codegen_ossfuzz
- test/tools/ossfuzz/strictasm_assembly_ossfuzz
- test/tools/ossfuzz/strictasm_diff_ossfuzz
- test/tools/ossfuzz/strictasm_opt_ossfuzz
- test/tools/ossfuzz/yul_proto_diff_ossfuzz
- test/tools/ossfuzz/yul_proto_diff_custom_mutate_ossfuzz
- test/tools/ossfuzz/yul_proto_ossfuzz
- test/tools/ossfuzz/sol_proto_ossfuzz
# test result output directory
- artifacts_test_results: &artifacts_test_results
path: test_results/
destination: test_results/
# --------------------------------------------------------------------------
# Step Templates
# store_test_results helper
- store_test_results: &store_test_results
path: test_results/
- steps_soltest: &steps_soltest
steps:
- checkout
- attach_workspace:
at: build
# NOTE: Different build jobs produce different soltest executables (release/debug,
# clang/gcc, windows/linux/macos, etc.). The executable used by these steps comes from the
# attached workspace and we only see the items added to the workspace by jobs we depend on.
- run: *run_soltest
- store_test_results: *store_test_results
- store_artifacts: *artifacts_test_results
- matrix_notify_failure_unless_pr
- steps_test_lsp: &steps_test_lsp
steps:
- checkout
- attach_workspace:
at: build
- run:
name: Install dependencies
command: pip install --user deepdiff colorama
- run:
name: Executing solc LSP test suite
command: ./test/lsp.py ./build/solc/solc --non-interactive
- matrix_notify_failure_unless_pr
- steps_build: &steps_build
steps:
- checkout
- run: *run_build
- store_artifacts: *artifacts_solc
- store_artifacts: *artifact_yul_phaser
- persist_to_workspace: *artifacts_executables
- matrix_notify_failure_unless_pr
- steps_soltest_all: &steps_soltest_all
steps:
- checkout
- attach_workspace:
at: build
- run: *run_soltest_all
- store_test_results: *store_test_results
- store_artifacts: *artifacts_test_results
- matrix_notify_failure_unless_pr
- steps_cmdline_tests: &steps_cmdline_tests
steps:
- checkout
- attach_workspace:
at: build
- run: *run_cmdline_tests
- store_test_results: *store_test_results
- store_artifacts: *artifacts_test_results
- matrix_notify_failure_unless_pr
- steps_install_dependencies_osx: &steps_install_dependencies_osx
steps:
# FIXME: We used to cache dependencies on macOS but now it takes longer than just installing
# them each time. See https://github.com/ethereum/solidity/issues/12925.
- run:
name: Install build dependencies
command: ./.circleci/osx_install_dependencies.sh
# --------------------------------------------------------------------------
# Base Image Templates
@ -767,7 +803,11 @@ jobs:
pip install --user codespell
- run:
name: Check spelling
command: ~/.local/bin/codespell --skip "*.enc,.git,Dockerfile*,LICENSE,codespell_whitelist.txt,codespell_ignored_lines.txt" --ignore-words ./scripts/codespell_whitelist.txt --exclude-file ./scripts/codespell_ignored_lines.txt
command: |
~/.local/bin/codespell \
--skip "*.enc,.git,Dockerfile*,LICENSE,codespell_whitelist.txt,codespell_ignored_lines.txt" \
--ignore-words scripts/codespell_whitelist.txt \
--exclude-file scripts/codespell_ignored_lines.txt
- matrix_notify_failure_unless_pr
chk_docs_examples:
@ -781,7 +821,7 @@ jobs:
command: sudo npm install -g solhint
- run:
name: Test Docs examples
command: ./test/docsCodeStyle.sh
command: test/docsCodeStyle.sh
- matrix_notify_failure_unless_pr
chk_coding_style:
@ -795,13 +835,13 @@ jobs:
sudo apt install -y shellcheck
- run:
name: Check for C++ coding style
command: ./scripts/check_style.sh
command: scripts/check_style.sh
- run:
name: checking shell scripts
command: ./scripts/chk_shellscripts/chk_shellscripts.sh
command: scripts/chk_shellscripts/chk_shellscripts.sh
- run:
name: Check for broken symlinks
command: ./scripts/check_symlinks.sh
command: scripts/check_symlinks.sh
- matrix_notify_failure_unless_pr
chk_errorcodes:
@ -810,7 +850,7 @@ jobs:
- checkout
- run:
name: Check for error codes
command: ./scripts/error_codes.py --check
command: scripts/error_codes.py --check
- matrix_notify_failure_unless_pr
chk_pylint:
@ -830,7 +870,7 @@ jobs:
- run: pylint --version
- run:
name: Linting Python Scripts
command: ./scripts/pylint_all.py
command: scripts/pylint_all.py
- matrix_notify_failure_unless_pr
chk_antlr_grammar:
@ -844,7 +884,7 @@ jobs:
sudo apt install -y openjdk-17-jdk
- run:
name: Run tests
command: ./scripts/test_antlr_grammar.sh
command: scripts/test_antlr_grammar.sh
- matrix_notify_failure_unless_pr
chk_buglist:
@ -859,7 +899,7 @@ jobs:
npm install mktemp
- run:
name: Test buglist
command: ./test/buglistTests.js
command: test/buglistTests.js
- matrix_notify_failure_unless_pr
chk_proofs:
@ -868,14 +908,14 @@ jobs:
- checkout
- install_python3:
packages: z3-solver
- run: *run_proofs
- run_proofs
- matrix_notify_failure_unless_pr
chk_docs_pragma_min_version:
<<: *base_ubuntu2204_small
steps:
- checkout
- run: *run_docs_pragma_min_version
- run_docs_pragma_min_version
- matrix_notify_failure_unless_pr
t_ubu_pyscripts:
@ -901,7 +941,8 @@ jobs:
# this runs 2x faster on xlarge but takes 4x more resources (compared to medium).
# Enough other jobs depend on it that it's worth it though.
<<: *base_ubuntu2204_xlarge
<<: *steps_build
steps:
- build
# x64 ASAN build, for testing for memory related bugs
b_ubu_asan: &b_ubu_asan
@ -911,14 +952,16 @@ jobs:
<<: *base_ubuntu2204_env
CMAKE_OPTIONS: -DSANITIZE=address
CMAKE_BUILD_TYPE: Release
<<: *steps_build
steps:
- build
b_ubu_clang: &b_ubu_clang
<<: *base_ubuntu2204_clang_large
environment:
<<: *base_ubuntu2204_clang_large_env
MAKEFLAGS: -j 10
<<: *steps_build
steps:
- build
b_ubu_san_clang:
# This runs a bit faster on large and xlarge but on nightly efficiency matters more.
@ -929,7 +972,8 @@ jobs:
environment:
<<: *base_ubuntu2204_clang_env
CMAKE_OPTIONS: << parameters.cmake_options >>
<<: *steps_build
steps:
- build
b_ubu_force_release: &b_ubu_force_release
<<: *b_ubu
@ -948,7 +992,7 @@ jobs:
CMAKE_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DUSE_Z3_DLOPEN=ON -DUSE_CVC4=OFF -DSOLC_STATIC_STDLIBS=ON
steps:
- checkout
- run: *run_build
- run_build
- run:
name: strip binary
command: strip build/solc/solc
@ -971,8 +1015,8 @@ jobs:
CMAKE_BUILD_TYPE: Debug
steps:
- checkout
- run: *run_build
- persist_to_workspace: *artifacts_executables
- run_build
- persist_executables_to_workspace
- matrix_notify_failure_unless_pr
t_ubu_codecov:
@ -991,11 +1035,11 @@ jobs:
- run:
name: "Code Coverage: Syntax Tests"
command: codecov --flags syntax --gcov-root build
- run: *run_soltest
- run_soltest
- run:
name: "Coverage: All"
command: codecov --flags all --gcov-root build
- store_artifacts: *artifacts_test_results
- store_artifacts_test_results
- matrix_notify_failure_unless_pr
# Builds in C++20 mode and uses debug build in order to speed up.
@ -1009,16 +1053,16 @@ jobs:
MAKEFLAGS: -j 10
steps:
- checkout
- run: *run_build
- run_build
- matrix_notify_failure_unless_pr
b_ubu_ossfuzz: &b_ubu_ossfuzz
<<: *base_ubuntu_clang
steps:
- checkout
- run: *setup_prerelease_commit_hash
- run: *run_build_ossfuzz
- persist_to_workspace: *artifacts_executables_ossfuzz
- setup_prerelease_commit_hash
- run_build_ossfuzz
- persist_ossfuzz_executables_to_workspace
- matrix_notify_failure_unless_pr
t_ubu_ossfuzz: &t_ubu_ossfuzz
@ -1033,8 +1077,9 @@ jobs:
git clone https://github.com/ethereum/solidity-fuzzing-corpus /tmp/solidity-fuzzing-corpus
mkdir -p test_results
scripts/regressions.py -o test_results
- store_test_results: *store_test_results
- store_artifacts: *artifacts_test_results
- store_test_results:
path: test_results/
- store_artifacts_test_results
b_archlinux:
<<: *base_archlinux_large
@ -1048,9 +1093,9 @@ jobs:
command: |
pacman --noconfirm -Syu --noprogressbar --needed base-devel boost cmake cvc4 git openssh tar
- checkout
- run: *run_build
- store_artifacts: *artifacts_solc
- persist_to_workspace: *artifacts_executables
- run_build
- store_artifacts_solc
- persist_executables_to_workspace
- matrix_notify_failure_unless_pr
b_osx:
@ -1060,18 +1105,11 @@ jobs:
CMAKE_BUILD_TYPE: Release
steps:
- checkout
- when:
condition: true
<<: *steps_install_dependencies_osx
- run: *run_build
- store_artifacts: *artifacts_solc
- store_artifacts: *artifact_yul_phaser
- persist_to_workspace:
root: .
paths:
- build/solc/solc
- build/test/soltest
- build/test/tools/solfuzzer
- install_dependencies_osx
- run_build
- store_artifacts_solc
- store_artifacts_yul_phaser
- persist_executables_to_workspace_osx
- matrix_notify_failure_unless_pr
t_osx_soltest: &t_osx_soltest
@ -1082,14 +1120,13 @@ jobs:
OPTIMIZE: 0
steps:
- checkout
- when:
condition: true
<<: *steps_install_dependencies_osx
- install_dependencies_osx
- attach_workspace:
at: .
- run: *run_soltest
- store_test_results: *store_test_results
- store_artifacts: *artifacts_test_results
- run_soltest
- store_test_results:
path: test_results/
- store_artifacts_test_results
- matrix_notify_failure_unless_pr
t_osx_cli:
@ -1097,13 +1134,11 @@ jobs:
parallelism: 7 # Should match number of tests in .circleci/cli.sh
steps:
- checkout
- when:
condition: true
<<: *steps_install_dependencies_osx
- install_dependencies_osx
- attach_workspace:
at: .
- run: *run_cmdline_tests
- store_artifacts: *artifacts_test_results
- run_cmdline_tests
- store_artifacts_test_results
- matrix_notify_failure_unless_pr
b_ems:
@ -1134,10 +1169,10 @@ jobs:
<<: *base_ubuntu2204_small
steps:
- checkout
- run: *setup_prerelease_commit_hash
- setup_prerelease_commit_hash
- run:
name: Build documentation
command: ./docs/docs.sh
command: docs/docs.sh
- store_artifacts:
path: docs/_build/html/
destination: docs-html
@ -1146,11 +1181,13 @@ jobs:
t_ubu_soltest_all: &t_ubu_soltest_all
<<: *base_ubuntu2204_large
parallelism: 50
<<: *steps_soltest_all
steps:
- soltest_all
t_ubu_lsp: &t_ubu_lsp
<<: *base_ubuntu2204_small
<<: *steps_test_lsp
steps:
- test_lsp
t_archlinux_soltest: &t_archlinux_soltest
<<: *base_archlinux
@ -1167,9 +1204,7 @@ jobs:
name: Install runtime dependencies
command: |
pacman --noconfirm -Syu --noprogressbar --needed base-devel boost cmake z3 cvc4 git openssh tar
- when:
condition: true
<<: *steps_soltest
- soltest
t_ubu_clang_soltest: &t_ubu_clang_soltest
<<: *base_ubuntu2204_clang
@ -1181,7 +1216,8 @@ jobs:
# The high parallelism in this job is causing the SMT tests to run out of memory,
# so disabling for now.
SOLTEST_FLAGS: --no-smt
<<: *steps_soltest
steps:
- soltest
t_ubu_force_release_soltest_all: &t_ubu_force_release_soltest_all
# NOTE: This definition is identical to t_ubu_soltest_all but in the workflow we make it depend on
@ -1191,7 +1227,8 @@ jobs:
t_ubu_cli: &t_ubu_cli
<<: *base_ubuntu2204_small
parallelism: 7 # Should match number of tests in .circleci/cli.sh
<<: *steps_cmdline_tests
steps:
- cmdline_tests
t_ubu_force_release_cli: &t_ubu_force_release_cli
<<: *t_ubu_cli
@ -1215,7 +1252,8 @@ jobs:
# Suppress CLN memory leak.
# See: https://github.com/ethereum/solidity/issues/13891 for details.
LSAN_OPTIONS: suppressions=/root/project/.circleci/cln-asan.supp:print_suppressions=0
<<: *steps_cmdline_tests
steps:
- cmdline_tests
t_ubu_asan_soltest:
<<: *base_ubuntu2204
@ -1229,7 +1267,8 @@ jobs:
# Suppress CLN memory leak.
# See: https://github.com/ethereum/solidity/issues/13891 for details.
LSAN_OPTIONS: suppressions=/root/project/.circleci/cln-asan.supp
<<: *steps_soltest
steps:
- soltest
t_ubu_asan_clang_soltest:
<<: *base_ubuntu2204_clang
@ -1240,7 +1279,8 @@ jobs:
OPTIMIZE: 0
SOLTEST_FLAGS: --no-smt
ASAN_OPTIONS: check_initialization_order=true:detect_stack_use_after_return=true:strict_init_order=true:strict_string_checks=true:detect_invalid_pointer_pairs=2
<<: *steps_soltest
steps:
- soltest
t_ubu_ubsan_clang_soltest:
<<: *base_ubuntu2204_clang
@ -1249,12 +1289,14 @@ jobs:
<<: *base_ubuntu2204_clang_env
EVM: << pipeline.parameters.evm-version >>
SOLTEST_FLAGS: --no-smt
<<: *steps_soltest
steps:
- soltest
t_ubu_ubsan_clang_cli:
<<: *base_ubuntu2204_clang
parallelism: 7 # Should match number of tests in .circleci/cli.sh
<<: *steps_cmdline_tests
steps:
- cmdline_tests
t_ems_solcjs:
# Unlike other t_ems jobs this one actually runs 2x faster on medium (compared to small).
@ -1478,7 +1520,8 @@ jobs:
name: "Run solc.exe to make sure build was successful."
command: .\build\solc\Release\solc.exe --version
shell: powershell.exe
- store_artifacts: *artifact_solc_windows
- store_artifacts:
path: upload/
- persist_to_workspace:
root: build
paths:
@ -1507,10 +1550,11 @@ jobs:
command: python -m pip install --user deepdiff colorama
- run:
name: Executing solc LSP test suite
command: python ./test/lsp.py .\build\solc\Release\solc.exe --non-interactive
command: python test/lsp.py build\solc\Release\solc.exe --non-interactive
shell: powershell.exe
- store_test_results: *store_test_results
- store_artifacts: *artifacts_test_results
- store_test_results:
path: test_results/
- store_artifacts_test_results
- matrix_notify_failure_unless_pr
# Note: b_bytecode_ubu_static is required because b_ubu_static and b_ubu

View File

@ -52,6 +52,8 @@ function validate_checksum {
if [ ! -f /usr/local/lib/libz3.a ] # if this file does not exists (cache was not restored), rebuild dependencies
then
brew update
brew upgrade
brew install boost
brew install cmake
brew install wget

View File

@ -4,7 +4,9 @@ Language Features:
Compiler Features:
* Parser: Remove the experimental error recovery mode (``--error-recovery`` / ``settings.parserErrorRecovery``).
* Yul Optimizer: If ``PUSH0`` is supported, favor zero literals over storing zero values in variables.
* Yul Optimizer: Run the ``Rematerializer`` and ``UnusedPruner`` steps at the end of the default clean-up sequence.
Bugfixes:

View File

@ -4,9 +4,9 @@ FetchContent_Declare(
fmtlib
PREFIX "${PROJECT_BINARY_DIR}/deps"
DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/deps/downloads"
DOWNLOAD_NAME fmt-8.0.1.tar.gz
URL https://github.com/fmtlib/fmt/archive/8.0.1.tar.gz
URL_HASH SHA256=b06ca3130158c625848f3fb7418f235155a4d389b2abc3a6245fb01cb0eb1e01
DOWNLOAD_NAME fmt-9.1.0.tar.gz
URL https://github.com/fmtlib/fmt/archive/9.1.0.tar.gz
URL_HASH SHA256=5dea48d1fcddc3ec571ce2058e13910a0d4a6bab4cc09a809d8b1dd1c88ae6f2
)
if (CMAKE_VERSION VERSION_LESS "3.14.0")

View File

@ -338,7 +338,7 @@ You can override this sequence and supply your own using the ``--yul-optimizatio
.. code-block:: bash
solc --optimize --ir-optimized --yul-optimizations 'dhfoD[xarrscLMcCTU]uljmul:fDnTOc'
solc --optimize --ir-optimized --yul-optimizations 'dhfoD[xarrscLMcCTU]uljmul:fDnTOcmu'
The order of steps is significant and affects the quality of the output.
Moreover, applying a step may uncover new optimization opportunities for others that were already applied,

View File

@ -109,7 +109,7 @@ public:
/// Resets any knowledge about storage.
void resetStorage() { m_storageContent.clear(); }
/// Resets any knowledge about storage.
/// Resets any knowledge about memory.
void resetMemory() { m_memoryContent.clear(); }
/// Resets known Keccak-256 hashes
void resetKnownKeccak256Hashes() { m_knownKeccak256Hashes.clear(); }

View File

@ -170,6 +170,8 @@ class Error: virtual public util::Exception
public:
enum class Type
{
Info,
Warning,
CodeGenerationError,
DeclarationError,
DocstringParsingError,
@ -185,15 +187,14 @@ public:
UnimplementedFeatureError,
YulException,
SMTLogicException,
Warning,
Info
};
enum class Severity
{
Error,
// NOTE: We rely on these being ordered from least to most severe.
Info,
Warning,
Info
Error,
};
Error(
@ -206,6 +207,7 @@ public:
ErrorId errorId() const { return m_errorId; }
Type type() const { return m_type; }
Severity severity() const { return errorSeverity(m_type); }
SourceLocation const* sourceLocation() const noexcept;
SecondarySourceLocation const* secondarySourceLocation() const noexcept;

View File

@ -74,56 +74,10 @@ void ParserBase::expectToken(Token _value, bool _advance)
{
Token tok = m_scanner->currentToken();
if (tok != _value)
{
std::string const expectedToken = ParserBase::tokenName(_value);
if (m_parserErrorRecovery)
parserError(6635_error, "Expected " + expectedToken + " but got " + tokenName(tok));
else
fatalParserError(2314_error, "Expected " + expectedToken + " but got " + tokenName(tok));
// Do not advance so that recovery can sync or make use of the current token.
// This is especially useful if the expected token
// is the only one that is missing and is at the end of a construct.
// "{ ... ; }" is such an example.
// ^
_advance = false;
}
if (_advance)
advance();
}
void ParserBase::expectTokenOrConsumeUntil(Token _value, std::string const& _currentNodeName, bool _advance)
{
solAssert(m_inParserRecovery, "The function is supposed to be called during parser recovery only.");
Token tok = m_scanner->currentToken();
if (tok != _value)
{
SourceLocation errorLoc = currentLocation();
int startPosition = errorLoc.start;
while (m_scanner->currentToken() != _value && m_scanner->currentToken() != Token::EOS)
advance();
std::string const expectedToken = ParserBase::tokenName(_value);
if (m_scanner->currentToken() == Token::EOS)
{
// rollback to where the token started, and raise exception to be caught at a higher level.
m_scanner->setPosition(static_cast<size_t>(startPosition));
std::string const msg = "In " + _currentNodeName + ", " + expectedToken + "is expected; got " + ParserBase::tokenName(tok) + " instead.";
fatalParserError(1957_error, errorLoc, msg);
}
else
{
parserWarning(3796_error, "Recovered in " + _currentNodeName + " at " + expectedToken + ".");
m_inParserRecovery = false;
}
}
else
{
std::string expectedToken = ParserBase::tokenName(_value);
parserWarning(3347_error, "Recovered in " + _currentNodeName + " at " + expectedToken + ".");
m_inParserRecovery = false;
}
fatalParserError(
2314_error,
"Expected " + ParserBase::tokenName(_value) + " but got " + tokenName(tok)
);
if (_advance)
advance();
}

View File

@ -38,14 +38,9 @@ struct ErrorId;
class ParserBase
{
public:
/// Set @a _parserErrorRecovery to true for additional error
/// recovery. This is experimental and intended for use
/// by front-end tools that need partial AST information even
/// when errors occur.
explicit ParserBase(ErrorReporter& errorReporter, bool _parserErrorRecovery = false): m_errorReporter(errorReporter)
{
m_parserErrorRecovery = _parserErrorRecovery;
}
explicit ParserBase(ErrorReporter& errorReporter):
m_errorReporter(errorReporter)
{}
virtual ~ParserBase() = default;
@ -70,13 +65,9 @@ protected:
///@{
///@name Helper functions
/// If current token value is not @a _value, throw exception otherwise advance token
// @a if _advance is true and error recovery is in effect.
// if @a _advance is true
void expectToken(Token _value, bool _advance = true);
/// Like expectToken but if there is an error ignores tokens until
/// the expected token or EOS is seen. If EOS is encountered, back up to the error point,
/// and throw an exception so that a higher grammar rule has an opportunity to recover.
void expectTokenOrConsumeUntil(Token _value, std::string const& _currentNodeName, bool _advance = true);
Token currentToken() const;
Token peekNextToken() const;
std::string tokenName(Token _token);
@ -108,10 +99,6 @@ protected:
ErrorReporter& m_errorReporter;
/// Current recursion depth during parsing.
size_t m_recursionDepth = 0;
/// True if we are in parser error recovery. Usually this means we are scanning for
/// a synchronization token like ';', or '}'. We use this to reduce cascaded error messages.
bool m_inParserRecovery = false;
bool m_parserErrorRecovery = false;
};
}

View File

@ -1019,15 +1019,28 @@ std::tuple<Token, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
while (isIdentifierPart(m_char) || (m_char == '.' && m_kind == ScannerKind::Yul))
addLiteralCharAndAdvance();
literal.complete();
auto const token = TokenTraits::fromIdentifierOrKeyword(m_tokens[NextNext].literal);
if (m_kind == ScannerKind::Yul)
switch (m_kind)
{
case ScannerKind::Solidity:
// Turn experimental Solidity keywords that are not keywords in legacy Solidity into identifiers.
if (TokenTraits::isExperimentalSolidityOnlyKeyword(std::get<0>(token)))
return std::make_tuple(Token::Identifier, 0, 0);
break;
case ScannerKind::Yul:
// Turn Solidity identifier into a Yul keyword
if (m_tokens[NextNext].literal == "leave")
return std::make_tuple(Token::Leave, 0, 0);
// Turn non-Yul keywords into identifiers.
if (!TokenTraits::isYulKeyword(std::get<0>(token)))
return std::make_tuple(Token::Identifier, 0, 0);
break;
case ScannerKind::ExperimentalSolidity:
// Turn legacy Solidity keywords that are not keywords in experimental Solidity into identifiers.
if (!TokenTraits::isExperimentalSolidityKeyword(std::get<0>(token)))
return std::make_tuple(Token::Identifier, 0, 0);
break;
}
return token;
}

View File

@ -69,7 +69,8 @@ class ParserRecorder;
enum class ScannerKind
{
Solidity,
Yul
Yul,
ExperimentalSolidity
};
enum class ScannerError

View File

@ -46,9 +46,16 @@ public:
bool _colored,
bool _withErrorIds
):
m_stream(_stream), m_charStreamProvider(_charStreamProvider), m_colored(_colored), m_withErrorIds(_withErrorIds)
m_stream(_stream),
m_charStreamProvider(_charStreamProvider),
m_colored(_colored),
m_withErrorIds(_withErrorIds)
{}
// WARNING: Use the xyzErrorInformation() variants over xyzExceptionInformation() when you
// do have access to an Error instance. Error is implicitly convertible to util::Exception
// but the conversion loses the error ID.
/// Prints source location if it is given.
void printSourceLocation(SourceReference const& _ref);
void printExceptionInformation(SourceReferenceExtractor::Message const& _msg);
@ -61,12 +68,11 @@ public:
util::Exception const& _exception,
Error::Type _type,
CharStreamProvider const& _charStreamProvider,
bool _colored = false,
bool _withErrorIds = false
bool _colored = false
)
{
std::ostringstream errorOutput;
SourceReferenceFormatter formatter(errorOutput, _charStreamProvider, _colored, _withErrorIds);
SourceReferenceFormatter formatter(errorOutput, _charStreamProvider, _colored, false /* _withErrorIds */);
formatter.printExceptionInformation(_exception, _type);
return errorOutput.str();
}
@ -75,26 +81,39 @@ public:
util::Exception const& _exception,
Error::Severity _severity,
CharStreamProvider const& _charStreamProvider,
bool _colored = false,
bool _withErrorIds = false
bool _colored = false
)
{
std::ostringstream errorOutput;
SourceReferenceFormatter formatter(errorOutput, _charStreamProvider, _colored, _withErrorIds);
SourceReferenceFormatter formatter(errorOutput, _charStreamProvider, _colored, false /* _withErrorIds */);
formatter.printExceptionInformation(_exception, _severity);
return errorOutput.str();
}
static std::string formatErrorInformation(
Error const& _error,
CharStreamProvider const& _charStreamProvider
CharStreamProvider const& _charStreamProvider,
bool _colored = false,
bool _withErrorIds = false
)
{
return formatExceptionInformation(
_error,
Error::errorSeverity(_error.type()),
_charStreamProvider
);
std::ostringstream errorOutput;
SourceReferenceFormatter formatter(errorOutput, _charStreamProvider, _colored, _withErrorIds);
formatter.printErrorInformation(_error);
return errorOutput.str();
}
static std::string formatErrorInformation(
langutil::ErrorList const& _errors,
CharStreamProvider const& _charStreamProvider,
bool _colored = false,
bool _withErrorIds = false
)
{
std::ostringstream errorOutput;
SourceReferenceFormatter formatter(errorOutput, _charStreamProvider, _colored, _withErrorIds);
formatter.printErrorInformation(_errors);
return errorOutput.str();
}
static std::string formatErrorInformation(Error const& _error, CharStream const& _charStream);

View File

@ -268,6 +268,8 @@ namespace solidity::langutil
/* Yul-specific tokens, but not keywords. */ \
T(Leave, "leave", 0) \
\
T(NonExperimentalEnd, nullptr, 0) /* used as non-experimental enum end marker */ \
T(ExperimentalEnd, nullptr, 0) /* used as experimental enum end marker */ \
/* Illegal token - not able to scan. */ \
T(Illegal, "ILLEGAL", 0) \
\
@ -323,6 +325,39 @@ namespace TokenTraits
tok == Token::TrueLiteral || tok == Token::FalseLiteral || tok == Token::HexStringLiteral || tok == Token::Hex;
}
constexpr bool isExperimentalSolidityKeyword(Token token)
{
return
token == Token::Assembly ||
token == Token::Contract ||
token == Token::External ||
token == Token::Fallback ||
token == Token::Pragma ||
token == Token::Import ||
token == Token::As ||
token == Token::Function ||
token == Token::Let ||
token == Token::Return ||
token == Token::Type ||
token == Token::If ||
token == Token::Else ||
token == Token::Do ||
token == Token::While ||
token == Token::For ||
token == Token::Continue ||
token == Token::Break;
// TODO: see isExperimentalSolidityKeyword below
// || (token > Token::NonExperimentalEnd && token < Token::ExperimentalEnd);
}
constexpr bool isExperimentalSolidityOnlyKeyword(Token)
{
// TODO: use token > Token::NonExperimentalEnd && token < Token::ExperimentalEnd
// as soon as other experimental tokens are added. For now the comparison generates
// a warning from clang because it is always false.
return false;
}
bool isYulKeyword(std::string const& _literal);
Token AssignmentToBinaryOp(Token op);

View File

@ -101,6 +101,8 @@ set(sources
codegen/ir/IRLValue.h
codegen/ir/IRVariable.cpp
codegen/ir/IRVariable.h
experimental/analysis/Analysis.cpp
experimental/analysis/Analysis.h
formal/ArraySlicePredicate.cpp
formal/ArraySlicePredicate.h
formal/BMC.cpp
@ -186,4 +188,3 @@ set(sources
add_library(solidity ${sources})
target_link_libraries(solidity PUBLIC yul evmasm langutil smtutil solutil Boost::boost fmt::fmt-header-only Threads::Threads)

View File

@ -29,7 +29,6 @@
#include <limits>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
using namespace solidity::langutil;
@ -47,9 +46,9 @@ bool fitsPrecisionExp(bigint const& _base, bigint const& _exp)
solAssert(_base > 0, "");
size_t const bitsMax = 4096;
std::size_t const bitsMax = 4096;
size_t mostSignificantBaseBit = static_cast<size_t>(boost::multiprecision::msb(_base));
std::size_t mostSignificantBaseBit = static_cast<std::size_t>(boost::multiprecision::msb(_base));
if (mostSignificantBaseBit == 0) // _base == 1
return true;
if (mostSignificantBaseBit > bitsMax) // _base >= 2 ^ 4096
@ -68,7 +67,7 @@ bool fitsPrecisionBase2(bigint const& _mantissa, uint32_t _expBase2)
}
optional<rational> ConstantEvaluator::evaluateBinaryOperator(Token _operator, rational const& _left, rational const& _right)
std::optional<rational> ConstantEvaluator::evaluateBinaryOperator(Token _operator, rational const& _left, rational const& _right)
{
bool fractional = _left.denominator() != 1 || _right.denominator() != 1;
switch (_operator)
@ -76,17 +75,17 @@ optional<rational> ConstantEvaluator::evaluateBinaryOperator(Token _operator, ra
//bit operations will only be enabled for integers and fixed types that resemble integers
case Token::BitOr:
if (fractional)
return nullopt;
return std::nullopt;
else
return _left.numerator() | _right.numerator();
case Token::BitXor:
if (fractional)
return nullopt;
return std::nullopt;
else
return _left.numerator() ^ _right.numerator();
case Token::BitAnd:
if (fractional)
return nullopt;
return std::nullopt;
else
return _left.numerator() & _right.numerator();
case Token::Add: return _left + _right;
@ -94,12 +93,12 @@ optional<rational> ConstantEvaluator::evaluateBinaryOperator(Token _operator, ra
case Token::Mul: return _left * _right;
case Token::Div:
if (_right == rational(0))
return nullopt;
return std::nullopt;
else
return _left / _right;
case Token::Mod:
if (_right == rational(0))
return nullopt;
return std::nullopt;
else if (fractional)
{
rational tempValue = _left / _right;
@ -111,7 +110,7 @@ optional<rational> ConstantEvaluator::evaluateBinaryOperator(Token _operator, ra
case Token::Exp:
{
if (_right.denominator() != 1)
return nullopt;
return std::nullopt;
bigint const& exp = _right.numerator();
// x ** 0 = 1
@ -127,13 +126,13 @@ optional<rational> ConstantEvaluator::evaluateBinaryOperator(Token _operator, ra
}
else
{
if (abs(exp) > numeric_limits<uint32_t>::max())
return nullopt; // This will need too much memory to represent.
if (abs(exp) > std::numeric_limits<uint32_t>::max())
return std::nullopt; // This will need too much memory to represent.
uint32_t absExp = bigint(abs(exp)).convert_to<uint32_t>();
if (!fitsPrecisionExp(abs(_left.numerator()), absExp) || !fitsPrecisionExp(abs(_left.denominator()), absExp))
return nullopt;
return std::nullopt;
static auto const optimizedPow = [](bigint const& _base, uint32_t _exponent) -> bigint {
if (_base == 1)
@ -158,18 +157,18 @@ optional<rational> ConstantEvaluator::evaluateBinaryOperator(Token _operator, ra
case Token::SHL:
{
if (fractional)
return nullopt;
return std::nullopt;
else if (_right < 0)
return nullopt;
else if (_right > numeric_limits<uint32_t>::max())
return nullopt;
return std::nullopt;
else if (_right > std::numeric_limits<uint32_t>::max())
return std::nullopt;
if (_left.numerator() == 0)
return 0;
else
{
uint32_t exponent = _right.numerator().convert_to<uint32_t>();
if (!fitsPrecisionBase2(abs(_left.numerator()), exponent))
return nullopt;
return std::nullopt;
return _left.numerator() * boost::multiprecision::pow(bigint(2), exponent);
}
break;
@ -179,11 +178,11 @@ optional<rational> ConstantEvaluator::evaluateBinaryOperator(Token _operator, ra
case Token::SAR:
{
if (fractional)
return nullopt;
return std::nullopt;
else if (_right < 0)
return nullopt;
else if (_right > numeric_limits<uint32_t>::max())
return nullopt;
return std::nullopt;
else if (_right > std::numeric_limits<uint32_t>::max())
return std::nullopt;
if (_left.numerator() == 0)
return 0;
else
@ -209,60 +208,60 @@ optional<rational> ConstantEvaluator::evaluateBinaryOperator(Token _operator, ra
break;
}
default:
return nullopt;
return std::nullopt;
}
}
optional<rational> ConstantEvaluator::evaluateUnaryOperator(Token _operator, rational const& _input)
std::optional<rational> ConstantEvaluator::evaluateUnaryOperator(Token _operator, rational const& _input)
{
switch (_operator)
{
case Token::BitNot:
if (_input.denominator() != 1)
return nullopt;
return std::nullopt;
else
return ~_input.numerator();
case Token::Sub:
return -_input;
default:
return nullopt;
return std::nullopt;
}
}
namespace
{
optional<TypedRational> convertType(rational const& _value, Type const& _type)
std::optional<TypedRational> convertType(rational const& _value, Type const& _type)
{
if (_type.category() == Type::Category::RationalNumber)
return TypedRational{TypeProvider::rationalNumber(_value), _value};
else if (auto const* integerType = dynamic_cast<IntegerType const*>(&_type))
{
if (_value > integerType->maxValue() || _value < integerType->minValue())
return nullopt;
return std::nullopt;
else
return TypedRational{&_type, _value.numerator() / _value.denominator()};
}
else
return nullopt;
return std::nullopt;
}
optional<TypedRational> convertType(optional<TypedRational> const& _value, Type const& _type)
std::optional<TypedRational> convertType(std::optional<TypedRational> const& _value, Type const& _type)
{
return _value ? convertType(_value->value, _type) : nullopt;
return _value ? convertType(_value->value, _type) : std::nullopt;
}
optional<TypedRational> constantToTypedValue(Type const& _type)
std::optional<TypedRational> constantToTypedValue(Type const& _type)
{
if (_type.category() == Type::Category::RationalNumber)
return TypedRational{&_type, dynamic_cast<RationalNumberType const&>(_type).value()};
else
return nullopt;
return std::nullopt;
}
}
optional<TypedRational> ConstantEvaluator::evaluate(
std::optional<TypedRational> ConstantEvaluator::evaluate(
langutil::ErrorReporter& _errorReporter,
Expression const& _expr
)
@ -271,7 +270,7 @@ optional<TypedRational> ConstantEvaluator::evaluate(
}
optional<TypedRational> ConstantEvaluator::evaluate(ASTNode const& _node)
std::optional<TypedRational> ConstantEvaluator::evaluate(ASTNode const& _node)
{
if (!m_values.count(&_node))
{
@ -280,7 +279,7 @@ optional<TypedRational> ConstantEvaluator::evaluate(ASTNode const& _node)
solAssert(varDecl->isConstant(), "");
// In some circumstances, we do not yet have a type for the variable.
if (!varDecl->value() || !varDecl->type())
m_values[&_node] = nullopt;
m_values[&_node] = std::nullopt;
else
{
m_depth++;
@ -298,7 +297,7 @@ optional<TypedRational> ConstantEvaluator::evaluate(ASTNode const& _node)
{
expression->accept(*this);
if (!m_values.count(&_node))
m_values[&_node] = nullopt;
m_values[&_node] = std::nullopt;
}
}
return m_values.at(&_node);
@ -306,7 +305,7 @@ optional<TypedRational> ConstantEvaluator::evaluate(ASTNode const& _node)
void ConstantEvaluator::endVisit(UnaryOperation const& _operation)
{
optional<TypedRational> value = evaluate(_operation.subExpression());
std::optional<TypedRational> value = evaluate(_operation.subExpression());
if (!value)
return;
@ -317,9 +316,9 @@ void ConstantEvaluator::endVisit(UnaryOperation const& _operation)
if (!value)
return;
if (optional<rational> result = evaluateUnaryOperator(_operation.getOperator(), value->value))
if (std::optional<rational> result = evaluateUnaryOperator(_operation.getOperator(), value->value))
{
optional<TypedRational> convertedValue = convertType(*result, *resultType);
std::optional<TypedRational> convertedValue = convertType(*result, *resultType);
if (!convertedValue)
m_errorReporter.fatalTypeError(
3667_error,
@ -332,8 +331,8 @@ void ConstantEvaluator::endVisit(UnaryOperation const& _operation)
void ConstantEvaluator::endVisit(BinaryOperation const& _operation)
{
optional<TypedRational> left = evaluate(_operation.leftExpression());
optional<TypedRational> right = evaluate(_operation.rightExpression());
std::optional<TypedRational> left = evaluate(_operation.leftExpression());
std::optional<TypedRational> right = evaluate(_operation.rightExpression());
if (!left || !right)
return;
@ -349,7 +348,7 @@ void ConstantEvaluator::endVisit(BinaryOperation const& _operation)
6020_error,
_operation.location(),
"Operator " +
string(TokenTraits::toString(_operation.getOperator())) +
std::string(TokenTraits::toString(_operation.getOperator())) +
" not compatible with types " +
left->type->toString() +
" and " +
@ -363,9 +362,9 @@ void ConstantEvaluator::endVisit(BinaryOperation const& _operation)
if (!left || !right)
return;
if (optional<rational> value = evaluateBinaryOperator(_operation.getOperator(), left->value, right->value))
if (std::optional<rational> value = evaluateBinaryOperator(_operation.getOperator(), left->value, right->value))
{
optional<TypedRational> convertedValue = convertType(*value, *resultType);
std::optional<TypedRational> convertedValue = convertType(*value, *resultType);
if (!convertedValue)
m_errorReporter.fatalTypeError(
2643_error,

View File

@ -32,7 +32,6 @@
#include <range/v3/view/reverse.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -49,10 +48,10 @@ bool hasEqualExternalCallableParameters(T const& _a, B const& _b)
}
template<typename T>
map<ASTString, vector<T const*>> filterDeclarations(
map<ASTString, vector<Declaration const*>> const& _declarations)
std::map<ASTString, std::vector<T const*>> filterDeclarations(
std::map<ASTString, std::vector<Declaration const*>> const& _declarations)
{
map<ASTString, vector<T const*>> filteredDeclarations;
std::map<ASTString, std::vector<T const*>> filteredDeclarations;
for (auto const& [name, overloads]: _declarations)
for (auto const* declaration: overloads)
if (auto typedDeclaration = dynamic_cast<T const*>(declaration))
@ -106,7 +105,7 @@ void ContractLevelChecker::checkDuplicateFunctions(ContractDefinition const& _co
{
/// Checks that two functions with the same name defined in this contract have different
/// argument types and that there is at most one constructor.
map<string, vector<FunctionDefinition const*>> functions;
std::map<std::string, std::vector<FunctionDefinition const*>> functions;
FunctionDefinition const* constructor = nullptr;
FunctionDefinition const* fallback = nullptr;
FunctionDefinition const* receive = nullptr;
@ -157,7 +156,7 @@ void ContractLevelChecker::checkDuplicateEvents(ContractDefinition const& _contr
{
/// Checks that two events with the same name defined in this contract have different
/// argument types
map<string, vector<EventDefinition const*>> events;
std::map<std::string, std::vector<EventDefinition const*>> events;
for (auto const* contract: _contract.annotation().linearizedBaseContracts)
for (EventDefinition const* event: contract->events())
events[event->name()].push_back(event);
@ -195,12 +194,12 @@ void ContractLevelChecker::checkReceiveFunction(ContractDefinition const& _contr
}
template <class T>
void ContractLevelChecker::findDuplicateDefinitions(map<string, vector<T>> const& _definitions)
void ContractLevelChecker::findDuplicateDefinitions(std::map<std::string, std::vector<T>> const& _definitions)
{
for (auto const& it: _definitions)
{
vector<T> const& overloads = it.second;
set<size_t> reported;
std::vector<T> const& overloads = it.second;
std::set<size_t> reported;
for (size_t i = 0; i < overloads.size() && !reported.count(i); ++i)
{
SecondarySourceLocation ssl;
@ -228,15 +227,15 @@ void ContractLevelChecker::findDuplicateDefinitions(map<string, vector<T>> const
if (ssl.infos.size() > 0)
{
ErrorId error;
string message;
if constexpr (is_same_v<T, FunctionDefinition const*>)
std::string message;
if constexpr (std::is_same_v<T, FunctionDefinition const*>)
{
error = 1686_error;
message = "Function with same name and parameter types defined twice.";
}
else
{
static_assert(is_same_v<T, EventDefinition const*>, "Expected \"FunctionDefinition const*\" or \"EventDefinition const*\"");
static_assert(std::is_same_v<T, EventDefinition const*>, "Expected \"FunctionDefinition const*\" or \"EventDefinition const*\"");
error = 5883_error;
message = "Event with same name and parameter types defined twice.";
}
@ -258,7 +257,7 @@ void ContractLevelChecker::checkAbstractDefinitions(ContractDefinition const& _c
{
// Collects functions, static variable getters and modifiers. If they
// override (unimplemented) base class ones, they are replaced.
set<OverrideProxy, OverrideProxy::CompareBySignature> proxies;
std::set<OverrideProxy, OverrideProxy::CompareBySignature> proxies;
auto registerProxy = [&proxies](OverrideProxy const& _overrideProxy)
{
@ -323,7 +322,7 @@ void ContractLevelChecker::checkAbstractDefinitions(ContractDefinition const& _c
void ContractLevelChecker::checkBaseConstructorArguments(ContractDefinition const& _contract)
{
vector<ContractDefinition const*> const& bases = _contract.annotation().linearizedBaseContracts;
std::vector<ContractDefinition const*> const& bases = _contract.annotation().linearizedBaseContracts;
// Determine the arguments that are used for the base constructors.
for (ContractDefinition const* contract: bases)
@ -430,7 +429,7 @@ void ContractLevelChecker::annotateBaseConstructorArguments(
void ContractLevelChecker::checkExternalTypeClashes(ContractDefinition const& _contract)
{
map<string, vector<pair<Declaration const*, FunctionTypePointer>>> externalDeclarations;
std::map<std::string, std::vector<std::pair<Declaration const*, FunctionTypePointer>>> externalDeclarations;
for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts)
{
for (FunctionDefinition const* f: contract->definedFunctions())
@ -467,7 +466,7 @@ void ContractLevelChecker::checkExternalTypeClashes(ContractDefinition const& _c
void ContractLevelChecker::checkHashCollisions(ContractDefinition const& _contract)
{
set<util::FixedHash<4>> hashes;
std::set<util::FixedHash<4>> hashes;
for (auto const& it: _contract.interfaceFunctionList())
{
util::FixedHash<4> const& hash = it.first;
@ -475,7 +474,7 @@ void ContractLevelChecker::checkHashCollisions(ContractDefinition const& _contra
m_errorReporter.fatalTypeError(
1860_error,
_contract.location(),
string("Function signature hash collision for ") + it.second->externalSignature()
std::string("Function signature hash collision for ") + it.second->externalSignature()
);
hashes.insert(hash);
}

View File

@ -25,7 +25,6 @@
#include <functional>
using namespace std;
using namespace std::placeholders;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -44,7 +43,7 @@ void ControlFlowAnalyzer::analyze(FunctionDefinition const& _function, ContractD
if (!_function.isImplemented())
return;
optional<string> mostDerivedContractName;
std::optional<std::string> mostDerivedContractName;
// The name of the most derived contract only required if it differs from
// the functions contract
@ -61,13 +60,13 @@ void ControlFlowAnalyzer::analyze(FunctionDefinition const& _function, ContractD
}
void ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNode const* _exit, bool _emptyBody, optional<string> _contractName)
void ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNode const* _exit, bool _emptyBody, std::optional<std::string> _contractName)
{
struct NodeInfo
{
set<VariableDeclaration const*> unassignedVariablesAtEntry;
set<VariableDeclaration const*> unassignedVariablesAtExit;
set<VariableOccurrence const*> uninitializedVariableAccesses;
std::set<VariableDeclaration const*> unassignedVariablesAtEntry;
std::set<VariableDeclaration const*> unassignedVariablesAtExit;
std::set<VariableOccurrence const*> uninitializedVariableAccesses;
/// Propagate the information from another node to this node.
/// To be used to propagate information from a node to its exit nodes.
/// Returns true, if new variables were added and thus the current node has
@ -84,8 +83,8 @@ void ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNod
;
}
};
map<CFGNode const*, NodeInfo> nodeInfos;
set<CFGNode const*> nodesToTraverse;
std::map<CFGNode const*, NodeInfo> nodeInfos;
std::set<CFGNode const*> nodesToTraverse;
nodesToTraverse.insert(_entry);
// Walk all paths starting from the nodes in ``nodesToTraverse`` until ``NodeInfo::propagateFrom``
@ -138,7 +137,7 @@ void ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNod
auto const& exitInfo = nodeInfos[_exit];
if (!exitInfo.uninitializedVariableAccesses.empty())
{
vector<VariableOccurrence const*> uninitializedAccessesOrdered(
std::vector<VariableOccurrence const*> uninitializedAccessesOrdered(
exitInfo.uninitializedVariableAccesses.begin(),
exitInfo.uninitializedVariableAccesses.end()
);
@ -168,7 +167,7 @@ void ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNod
varDecl.location(),
ssl,
"This variable is of " +
string(isStorage ? "storage" : "calldata") +
std::string(isStorage ? "storage" : "calldata") +
" pointer type and can be " +
(variableOccurrence->kind() == VariableOccurrence::Kind::Return ? "returned" : "accessed") +
" without prior assignment, which would lead to undefined behaviour."

View File

@ -21,10 +21,8 @@
#include <libyul/AST.h>
#include <libyul/backends/evm/EVMDialect.h>
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::frontend;
using namespace std;
ControlFlowBuilder::ControlFlowBuilder(CFG::NodeContainer& _nodeContainer, FunctionFlow const& _functionFlow, ContractDefinition const* _contract):
m_nodeContainer(_nodeContainer),
@ -37,13 +35,13 @@ ControlFlowBuilder::ControlFlowBuilder(CFG::NodeContainer& _nodeContainer, Funct
}
unique_ptr<FunctionFlow> ControlFlowBuilder::createFunctionFlow(
std::unique_ptr<FunctionFlow> ControlFlowBuilder::createFunctionFlow(
CFG::NodeContainer& _nodeContainer,
FunctionDefinition const& _function,
ContractDefinition const* _contract
)
{
auto functionFlow = make_unique<FunctionFlow>();
auto functionFlow = std::make_unique<FunctionFlow>();
functionFlow->entry = _nodeContainer.newNode();
functionFlow->exit = _nodeContainer.newNode();
functionFlow->revert = _nodeContainer.newNode();

View File

@ -20,7 +20,6 @@
#include <libsolidity/analysis/ControlFlowBuilder.h>
using namespace std;
using namespace solidity::langutil;
using namespace solidity::frontend;

View File

@ -29,7 +29,6 @@
#include <range/v3/view/filter.hpp>
#include <range/v3/range/conversion.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
@ -41,7 +40,7 @@ Declaration const* DeclarationContainer::conflictingDeclaration(
if (!_name)
_name = &_declaration.name();
solAssert(!_name->empty(), "");
vector<Declaration const*> declarations;
std::vector<Declaration const*> declarations;
if (m_declarations.count(*_name))
declarations += m_declarations.at(*_name);
if (m_invisibleDeclarations.count(*_name))
@ -127,7 +126,7 @@ bool DeclarationContainer::registerDeclaration(
m_homonymCandidates.emplace_back(*_name, _location ? _location : &_declaration.location());
}
vector<Declaration const*>& decls = _invisible ? m_invisibleDeclarations[*_name] : m_declarations[*_name];
std::vector<Declaration const*>& decls = _invisible ? m_invisibleDeclarations[*_name] : m_declarations[*_name];
if (!util::contains(decls, &_declaration))
decls.push_back(&_declaration);
return true;
@ -142,13 +141,13 @@ bool DeclarationContainer::registerDeclaration(
return registerDeclaration(_declaration, nullptr, nullptr, _invisible, _update);
}
vector<Declaration const*> DeclarationContainer::resolveName(
std::vector<Declaration const*> DeclarationContainer::resolveName(
ASTString const& _name,
ResolvingSettings _settings
) const
{
solAssert(!_name.empty(), "Attempt to resolve empty name.");
vector<Declaration const*> result;
std::vector<Declaration const*> result;
if (m_declarations.count(_name))
{
@ -172,24 +171,24 @@ vector<Declaration const*> DeclarationContainer::resolveName(
return result;
}
vector<ASTString> DeclarationContainer::similarNames(ASTString const& _name) const
std::vector<ASTString> DeclarationContainer::similarNames(ASTString const& _name) const
{
// because the function below has quadratic runtime - it will not magically improve once a better algorithm is discovered ;)
// since 80 is the suggested line length limit, we use 80^2 as length threshold
static size_t const MAXIMUM_LENGTH_THRESHOLD = 80 * 80;
vector<ASTString> similar;
std::vector<ASTString> similar;
size_t maximumEditDistance = _name.size() > 3 ? 2 : _name.size() / 2;
for (auto const& declaration: m_declarations)
{
string const& declarationName = declaration.first;
std::string const& declarationName = declaration.first;
if (util::stringWithinDistance(_name, declarationName, maximumEditDistance, MAXIMUM_LENGTH_THRESHOLD))
similar.push_back(declarationName);
}
for (auto const& declaration: m_invisibleDeclarations)
{
string const& declarationName = declaration.first;
std::string const& declarationName = declaration.first;
if (util::stringWithinDistance(_name, declarationName, maximumEditDistance, MAXIMUM_LENGTH_THRESHOLD))
similar.push_back(declarationName);
}
@ -200,7 +199,7 @@ vector<ASTString> DeclarationContainer::similarNames(ASTString const& _name) con
return similar;
}
void DeclarationContainer::populateHomonyms(back_insert_iterator<Homonyms> _it) const
void DeclarationContainer::populateHomonyms(std::back_insert_iterator<Homonyms> _it) const
{
for (DeclarationContainer const* innerContainer: m_innerContainers)
innerContainer->populateHomonyms(_it);
@ -210,7 +209,7 @@ void DeclarationContainer::populateHomonyms(back_insert_iterator<Homonyms> _it)
ResolvingSettings settings;
settings.recursive = true;
settings.alsoInvisible = true;
vector<Declaration const*> const& declarations = m_enclosingContainer->resolveName(name, std::move(settings));
std::vector<Declaration const*> const& declarations = m_enclosingContainer->resolveName(name, std::move(settings));
if (!declarations.empty())
_it = make_pair(location, declarations);
}

View File

@ -29,7 +29,6 @@
#include <range/v3/view/transform.hpp>
using namespace std;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -336,10 +335,10 @@ void DeclarationTypeChecker::endVisit(ArrayTypeName const& _typeName)
if (Expression const* length = _typeName.length())
{
optional<rational> lengthValue;
std::optional<rational> lengthValue;
if (length->annotation().type && length->annotation().type->category() == Type::Category::RationalNumber)
lengthValue = dynamic_cast<RationalNumberType const&>(*length->annotation().type).value();
else if (optional<ConstantEvaluator::TypedRational> value = ConstantEvaluator::evaluate(m_errorReporter, *length))
else if (std::optional<ConstantEvaluator::TypedRational> value = ConstantEvaluator::evaluate(m_errorReporter, *length))
lengthValue = value->value;
if (!lengthValue)
@ -399,10 +398,10 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable)
Location varLoc = _variable.referenceLocation();
DataLocation typeLoc = DataLocation::Memory;
set<Location> allowedDataLocations = _variable.allowedDataLocations();
std::set<Location> allowedDataLocations = _variable.allowedDataLocations();
if (!allowedDataLocations.count(varLoc))
{
auto locationToString = [](VariableDeclaration::Location _location) -> string
auto locationToString = [](VariableDeclaration::Location _location) -> std::string
{
switch (_location)
{
@ -414,7 +413,7 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable)
return {};
};
string errorString;
std::string errorString;
if (!_variable.hasReferenceOrMappingType())
errorString = "Data location can only be specified for array, struct or mapping types";
else
@ -430,9 +429,9 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable)
else if (_variable.isCallableOrCatchParameter())
errorString +=
" for " +
string(_variable.isReturnParameter() ? "return " : "") +
std::string(_variable.isReturnParameter() ? "return " : "") +
"parameter in" +
string(_variable.isExternalCallableParameter() ? " external" : "") +
std::string(_variable.isExternalCallableParameter() ? " external" : "") +
" function";
else
errorString += " for variable";

View File

@ -30,7 +30,6 @@
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -38,7 +37,7 @@ using namespace solidity::frontend;
namespace
{
void copyMissingTags(set<CallableDeclaration const*> const& _baseFunctions, StructurallyDocumentedAnnotation& _target, FunctionType const* _functionType = nullptr)
void copyMissingTags(std::set<CallableDeclaration const*> const& _baseFunctions, StructurallyDocumentedAnnotation& _target, FunctionType const* _functionType = nullptr)
{
// Only copy if there is exactly one direct base function.
if (_baseFunctions.size() != 1)
@ -50,7 +49,7 @@ void copyMissingTags(set<CallableDeclaration const*> const& _baseFunctions, Stru
for (auto it = sourceDoc.docTags.begin(); it != sourceDoc.docTags.end();)
{
string const& tag = it->first;
std::string const& tag = it->first;
// Don't copy tag "inheritdoc", custom tags or already existing tags
if (tag == "inheritdoc" || _target.docTags.count(tag) || boost::starts_with(tag, "custom"))
{
@ -68,7 +67,7 @@ void copyMissingTags(set<CallableDeclaration const*> const& _baseFunctions, Stru
if (_functionType && tag == "return")
{
size_t docParaNameEndPos = content.content.find_first_of(" \t");
string const docParameterName = content.content.substr(0, docParaNameEndPos);
std::string const docParameterName = content.content.substr(0, docParaNameEndPos);
if (
_functionType->returnParameterNames().size() > n &&
@ -80,10 +79,10 @@ void copyMissingTags(set<CallableDeclaration const*> const& _baseFunctions, Stru
baseFunction.returnParameters().size() > n &&
baseFunction.returnParameters().at(n)->name().empty();
string paramName = _functionType->returnParameterNames().at(n);
std::string paramName = _functionType->returnParameterNames().at(n);
content.content =
(paramName.empty() ? "" : std::move(paramName) + " ") + (
string::npos == docParaNameEndPos || baseHasNoName ?
std::string::npos == docParaNameEndPos || baseHasNoName ?
content.content :
content.content.substr(docParaNameEndPos + 1)
);
@ -95,7 +94,7 @@ void copyMissingTags(set<CallableDeclaration const*> const& _baseFunctions, Stru
}
}
CallableDeclaration const* findBaseCallable(set<CallableDeclaration const*> const& _baseFunctions, int64_t _contractId)
CallableDeclaration const* findBaseCallable(std::set<CallableDeclaration const*> const& _baseFunctions, int64_t _contractId)
{
for (CallableDeclaration const* baseFuncCandidate: _baseFunctions)
if (baseFuncCandidate->annotation().contract->id() == _contractId)
@ -181,7 +180,7 @@ void DocStringAnalyser::handleCallable(
}
CallableDeclaration const* DocStringAnalyser::resolveInheritDoc(
set<CallableDeclaration const*> const& _baseFuncs,
std::set<CallableDeclaration const*> const& _baseFuncs,
StructurallyDocumented const& _node,
StructurallyDocumentedAnnotation& _annotation
)

View File

@ -37,7 +37,6 @@
#include <regex>
#include <string_view>
using namespace std;
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -67,7 +66,7 @@ bool DocStringTagParser::validateDocStringsUsingTypes(SourceUnit const& _sourceU
if (tagName == "return")
{
returnTagsVisited++;
vector<string> returnParameterNames;
std::vector<std::string> returnParameterNames;
if (auto const* varDecl = dynamic_cast<VariableDeclaration const*>(&_node))
{
@ -82,8 +81,8 @@ bool DocStringTagParser::validateDocStringsUsingTypes(SourceUnit const& _sourceU
else
continue;
string content = tagValue.content;
string firstWord = content.substr(0, content.find_first_of(" \t"));
std::string content = tagValue.content;
std::string firstWord = content.substr(0, content.find_first_of(" \t"));
if (returnTagsVisited > returnParameterNames.size())
m_errorReporter.docstringParsingError(
@ -94,7 +93,7 @@ bool DocStringTagParser::validateDocStringsUsingTypes(SourceUnit const& _sourceU
);
else
{
string const& parameter = returnParameterNames.at(returnTagsVisited - 1);
std::string const& parameter = returnParameterNames.at(returnTagsVisited - 1);
if (!parameter.empty() && parameter != firstWord)
m_errorReporter.docstringParsingError(
5856_error,
@ -113,7 +112,7 @@ bool DocStringTagParser::validateDocStringsUsingTypes(SourceUnit const& _sourceU
bool DocStringTagParser::visit(ContractDefinition const& _contract)
{
static set<string> const validTags = set<string>{"author", "title", "dev", "notice"};
static std::set<std::string> const validTags = std::set<std::string>{"author", "title", "dev", "notice"};
parseDocStrings(_contract, _contract.annotation(), validTags, "contracts");
return true;
@ -193,12 +192,12 @@ bool DocStringTagParser::visit(InlineAssembly const& _assembly)
{
if (tagName == "solidity")
{
vector<string> values;
std::vector<std::string> values;
boost::split(values, tagValue.content, isWhiteSpace);
set<string> valuesSeen;
set<string> duplicates;
for (auto const& value: values | ranges::views::filter(not_fn(&string::empty)))
std::set<std::string> valuesSeen;
std::set<std::string> duplicates;
for (auto const& value: values | ranges::views::filter(not_fn(&std::string::empty)))
if (valuesSeen.insert(value).second)
{
if (value == "memory-safe-assembly")
@ -244,7 +243,7 @@ void DocStringTagParser::checkParameters(
StructurallyDocumentedAnnotation& _annotation
)
{
set<string> validParams;
std::set<std::string> validParams;
for (auto const& p: _callable.parameters())
validParams.insert(p->name());
if (_callable.returnParameterList())
@ -268,7 +267,7 @@ void DocStringTagParser::handleConstructor(
StructurallyDocumentedAnnotation& _annotation
)
{
static set<string> const validTags = set<string>{"author", "dev", "notice", "param"};
static std::set<std::string> const validTags = std::set<std::string>{"author", "dev", "notice", "param"};
parseDocStrings(_node, _annotation, validTags, "constructor");
checkParameters(_callable, _node, _annotation);
}
@ -279,10 +278,10 @@ void DocStringTagParser::handleCallable(
StructurallyDocumentedAnnotation& _annotation
)
{
static set<string> const validEventTags = set<string>{"dev", "notice", "return", "param"};
static set<string> const validErrorTags = set<string>{"dev", "notice", "param"};
static set<string> const validModifierTags = set<string>{"dev", "notice", "param", "inheritdoc"};
static set<string> const validTags = set<string>{"dev", "notice", "return", "param", "inheritdoc"};
static std::set<std::string> const validEventTags = std::set<std::string>{"dev", "notice", "return", "param"};
static std::set<std::string> const validErrorTags = std::set<std::string>{"dev", "notice", "param"};
static std::set<std::string> const validModifierTags = std::set<std::string>{"dev", "notice", "param", "inheritdoc"};
static std::set<std::string> const validTags = std::set<std::string>{"dev", "notice", "return", "param", "inheritdoc"};
if (dynamic_cast<EventDefinition const*>(&_callable))
parseDocStrings(_node, _annotation, validEventTags, "events");
@ -299,8 +298,8 @@ void DocStringTagParser::handleCallable(
void DocStringTagParser::parseDocStrings(
StructurallyDocumented const& _node,
StructurallyDocumentedAnnotation& _annotation,
set<string> const& _validTags,
string const& _nodeName
std::set<std::string> const& _validTags,
std::string const& _nodeName
)
{
if (!_node.documentation())
@ -310,7 +309,7 @@ void DocStringTagParser::parseDocStrings(
for (auto const& [tagName, tagValue]: _annotation.docTags)
{
string_view static constexpr customPrefix("custom:");
std::string_view static constexpr customPrefix("custom:");
if (tagName == "custom" || tagName == "custom:")
m_errorReporter.docstringParsingError(
6564_error,
@ -319,7 +318,7 @@ void DocStringTagParser::parseDocStrings(
);
else if (boost::starts_with(tagName, customPrefix) && tagName.size() > customPrefix.size())
{
regex static const customRegex("^custom:[a-z][a-z-]*$");
std::regex static const customRegex("^custom:[a-z][a-z-]*$");
if (!regex_match(tagName, customRegex))
m_errorReporter.docstringParsingError(
2968_error,

View File

@ -24,7 +24,6 @@
#include <range/v3/view/reverse.hpp>
#include <range/v3/view/transform.hpp>
using namespace std;
using namespace solidity::frontend;
using namespace solidity::util;
@ -72,7 +71,7 @@ CallGraph FunctionCallGraphBuilder::buildDeployedGraph(
FunctionCallGraphBuilder builder(_contract);
solAssert(builder.m_currentNode == CallGraph::Node(CallGraph::SpecialNode::Entry), "");
auto getSecondElement = [](auto const& _tuple){ return get<1>(_tuple); };
auto getSecondElement = [](auto const& _tuple){ return std::get<1>(_tuple); };
// Create graph for all publicly reachable functions
for (FunctionTypePointer functionType: _contract.interfaceFunctionList() | ranges::views::transform(getSecondElement))
@ -96,14 +95,14 @@ CallGraph FunctionCallGraphBuilder::buildDeployedGraph(
// All functions present in internal dispatch at creation time could potentially be pointers
// assigned to state variables and as such may be reachable after deployment as well.
builder.m_currentNode = CallGraph::SpecialNode::InternalDispatch;
set<CallGraph::Node, CallGraph::CompareByID> defaultNode;
std::set<CallGraph::Node, CallGraph::CompareByID> defaultNode;
for (CallGraph::Node const& dispatchTarget: util::valueOrDefault(_creationGraph.edges, CallGraph::SpecialNode::InternalDispatch, defaultNode))
{
solAssert(!holds_alternative<CallGraph::SpecialNode>(dispatchTarget), "");
solAssert(get<CallableDeclaration const*>(dispatchTarget) != nullptr, "");
solAssert(!std::holds_alternative<CallGraph::SpecialNode>(dispatchTarget), "");
solAssert(std::get<CallableDeclaration const*>(dispatchTarget) != nullptr, "");
// Visit the callable to add not only it but also everything it calls too
builder.functionReferenced(*get<CallableDeclaration const*>(dispatchTarget), false);
builder.functionReferenced(*std::get<CallableDeclaration const*>(dispatchTarget), false);
}
builder.m_currentNode = CallGraph::SpecialNode::Entry;
@ -262,10 +261,10 @@ void FunctionCallGraphBuilder::processQueue()
while (!m_visitQueue.empty())
{
m_currentNode = m_visitQueue.front();
solAssert(holds_alternative<CallableDeclaration const*>(m_currentNode), "");
solAssert(std::holds_alternative<CallableDeclaration const*>(m_currentNode), "");
m_visitQueue.pop_front();
get<CallableDeclaration const*>(m_currentNode)->accept(*this);
std::get<CallableDeclaration const*>(m_currentNode)->accept(*this);
}
m_currentNode = CallGraph::SpecialNode::Entry;
@ -281,7 +280,7 @@ void FunctionCallGraphBuilder::functionReferenced(CallableDeclaration const& _ca
if (_calledDirectly)
{
solAssert(
holds_alternative<CallGraph::SpecialNode>(m_currentNode) || m_graph.edges.count(m_currentNode) > 0,
std::holds_alternative<CallGraph::SpecialNode>(m_currentNode) || m_graph.edges.count(m_currentNode) > 0,
"Adding an edge from a node that has not been visited yet."
);
@ -293,10 +292,10 @@ void FunctionCallGraphBuilder::functionReferenced(CallableDeclaration const& _ca
enqueueCallable(_callable);
}
ostream& solidity::frontend::operator<<(ostream& _out, CallGraph::Node const& _node)
std::ostream& solidity::frontend::operator<<(std::ostream& _out, CallGraph::Node const& _node)
{
if (holds_alternative<CallGraph::SpecialNode>(_node))
switch (get<CallGraph::SpecialNode>(_node))
if (std::holds_alternative<CallGraph::SpecialNode>(_node))
switch (std::get<CallGraph::SpecialNode>(_node))
{
case CallGraph::SpecialNode::InternalDispatch:
_out << "InternalDispatch";
@ -309,19 +308,19 @@ ostream& solidity::frontend::operator<<(ostream& _out, CallGraph::Node const& _n
}
else
{
solAssert(holds_alternative<CallableDeclaration const*>(_node), "");
solAssert(std::holds_alternative<CallableDeclaration const*>(_node), "");
auto const* callableDeclaration = get<CallableDeclaration const*>(_node);
auto const* callableDeclaration = std::get<CallableDeclaration const*>(_node);
solAssert(callableDeclaration, "");
auto const* function = dynamic_cast<FunctionDefinition const *>(callableDeclaration);
auto const* event = dynamic_cast<EventDefinition const *>(callableDeclaration);
auto const* modifier = dynamic_cast<ModifierDefinition const *>(callableDeclaration);
auto typeToString = [](auto const& _var) -> string { return _var->type()->toString(true); };
vector<string> parameters = callableDeclaration->parameters() | ranges::views::transform(typeToString) | ranges::to<vector<string>>();
auto typeToString = [](auto const& _var) -> std::string { return _var->type()->toString(true); };
std::vector<std::string> parameters = callableDeclaration->parameters() | ranges::views::transform(typeToString) | ranges::to<std::vector<std::string>>();
string scopeName;
std::string scopeName;
if (!function || !function->isFree())
{
solAssert(callableDeclaration->annotation().scope, "");

View File

@ -29,8 +29,6 @@
#include <libsolidity/ast/Types.h>
#include <memory>
using namespace std;
namespace solidity::frontend
{
@ -65,10 +63,10 @@ int magicVariableToID(std::string const& _name)
solAssert(false, "Unknown magic variable: \"" + _name + "\".");
}
inline vector<shared_ptr<MagicVariableDeclaration const>> constructMagicVariables()
inline std::vector<std::shared_ptr<MagicVariableDeclaration const>> constructMagicVariables()
{
static auto const magicVarDecl = [](string const& _name, Type const* _type) {
return make_shared<MagicVariableDeclaration>(magicVariableToID(_name), _name, _type);
static auto const magicVarDecl = [](std::string const& _name, Type const* _type) {
return std::make_shared<MagicVariableDeclaration>(magicVariableToID(_name), _name, _type);
};
return {
@ -116,9 +114,9 @@ void GlobalContext::setCurrentContract(ContractDefinition const& _contract)
m_currentContract = &_contract;
}
vector<Declaration const*> GlobalContext::declarations() const
std::vector<Declaration const*> GlobalContext::declarations() const
{
vector<Declaration const*> declarations;
std::vector<Declaration const*> declarations;
declarations.reserve(m_magicVariables.size());
for (ASTPointer<MagicVariableDeclaration const> const& variable: m_magicVariables)
declarations.push_back(variable.get());
@ -133,7 +131,7 @@ MagicVariableDeclaration const* GlobalContext::currentThis() const
if (m_currentContract)
type = TypeProvider::contract(*m_currentContract);
m_thisPointer[m_currentContract] =
make_shared<MagicVariableDeclaration>(magicVariableToID("this"), "this", type);
std::make_shared<MagicVariableDeclaration>(magicVariableToID("this"), "this", type);
}
return m_thisPointer[m_currentContract].get();
}
@ -146,7 +144,7 @@ MagicVariableDeclaration const* GlobalContext::currentSuper() const
if (m_currentContract)
type = TypeProvider::typeType(TypeProvider::contract(*m_currentContract, true));
m_superPointer[m_currentContract] =
make_shared<MagicVariableDeclaration>(magicVariableToID("super"), "super", type);
std::make_shared<MagicVariableDeclaration>(magicVariableToID("super"), "super", type);
}
return m_superPointer[m_currentContract].get();
}

View File

@ -30,7 +30,6 @@
#include <boost/algorithm/string.hpp>
#include <unordered_set>
using namespace std;
using namespace solidity::langutil;
namespace solidity::frontend
@ -45,7 +44,7 @@ NameAndTypeResolver::NameAndTypeResolver(
m_errorReporter(_errorReporter),
m_globalContext(_globalContext)
{
m_scopes[nullptr] = make_shared<DeclarationContainer>();
m_scopes[nullptr] = std::make_shared<DeclarationContainer>();
for (Declaration const* declaration: _globalContext.declarations())
{
solAssert(m_scopes[nullptr]->registerDeclaration(*declaration, false, false), "Unable to register global declaration.");
@ -68,14 +67,14 @@ bool NameAndTypeResolver::registerDeclarations(SourceUnit& _sourceUnit, ASTNode
return true;
}
bool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, map<string, SourceUnit const*> const& _sourceUnits)
bool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, std::map<std::string, SourceUnit const*> const& _sourceUnits)
{
DeclarationContainer& target = *m_scopes.at(&_sourceUnit);
bool error = false;
for (auto const& node: _sourceUnit.nodes())
if (auto imp = dynamic_cast<ImportDirective const*>(node.get()))
{
string const& path = *imp->annotation().absolutePath;
std::string const& path = *imp->annotation().absolutePath;
// The import resolution in CompilerStack enforces this.
solAssert(_sourceUnits.count(path), "");
auto scope = m_scopes.find(_sourceUnits.at(path));
@ -127,7 +126,7 @@ bool NameAndTypeResolver::resolveNamesAndTypes(SourceUnit& _source)
{
try
{
for (shared_ptr<ASTNode> const& node: _source.nodes())
for (std::shared_ptr<ASTNode> const& node: _source.nodes())
{
setScope(&_source);
if (!resolveNamesAndTypesInternal(*node, true))
@ -159,7 +158,7 @@ bool NameAndTypeResolver::updateDeclaration(Declaration const& _declaration)
return true;
}
void NameAndTypeResolver::activateVariable(string const& _name)
void NameAndTypeResolver::activateVariable(std::string const& _name)
{
solAssert(m_currentScope, "");
// Scoped local variables are invisible before activation.
@ -171,15 +170,15 @@ void NameAndTypeResolver::activateVariable(string const& _name)
m_currentScope->activateVariable(_name);
}
vector<Declaration const*> NameAndTypeResolver::resolveName(ASTString const& _name, ASTNode const* _scope) const
std::vector<Declaration const*> NameAndTypeResolver::resolveName(ASTString const& _name, ASTNode const* _scope) const
{
auto iterator = m_scopes.find(_scope);
if (iterator == end(m_scopes))
return vector<Declaration const*>({});
return std::vector<Declaration const*>({});
return iterator->second->resolveName(_name);
}
vector<Declaration const*> NameAndTypeResolver::nameFromCurrentScope(ASTString const& _name, bool _includeInvisibles) const
std::vector<Declaration const*> NameAndTypeResolver::nameFromCurrentScope(ASTString const& _name, bool _includeInvisibles) const
{
ResolvingSettings settings;
settings.recursive = true;
@ -187,7 +186,7 @@ vector<Declaration const*> NameAndTypeResolver::nameFromCurrentScope(ASTString c
return m_currentScope->resolveName(_name, std::move(settings));
}
Declaration const* NameAndTypeResolver::pathFromCurrentScope(vector<ASTString> const& _path) const
Declaration const* NameAndTypeResolver::pathFromCurrentScope(std::vector<ASTString> const& _path) const
{
if (auto declarations = pathFromCurrentScopeWithAllDeclarations(_path); !declarations.empty())
return declarations.back();
@ -201,13 +200,13 @@ std::vector<Declaration const*> NameAndTypeResolver::pathFromCurrentScopeWithAll
) const
{
solAssert(!_path.empty(), "");
vector<Declaration const*> pathDeclarations;
std::vector<Declaration const*> pathDeclarations;
ResolvingSettings settings;
settings.recursive = true;
settings.alsoInvisible = _includeInvisibles;
settings.onlyVisibleAsUnqualifiedNames = true;
vector<Declaration const*> candidates = m_currentScope->resolveName(_path.front(), settings);
std::vector<Declaration const*> candidates = m_currentScope->resolveName(_path.front(), settings);
// inside the loop, use default settings, except for alsoInvisible
settings.recursive = false;
@ -305,7 +304,7 @@ bool NameAndTypeResolver::resolveNamesAndTypesInternal(ASTNode& _node, bool _res
if (success)
{
linearizeBaseContracts(*contract);
vector<ContractDefinition const*> properBases(
std::vector<ContractDefinition const*> properBases(
++contract->annotation().linearizedBaseContracts.begin(),
contract->annotation().linearizedBaseContracts.end()
);
@ -405,7 +404,7 @@ void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract)
{
// order in the lists is from derived to base
// list of lists to linearize, the last element is the list of direct bases
list<list<ContractDefinition const*>> input(1, list<ContractDefinition const*>{});
std::list<std::list<ContractDefinition const*>> input(1, std::list<ContractDefinition const*>{});
for (ASTPointer<InheritanceSpecifier> const& baseSpecifier: _contract.baseContracts())
{
IdentifierPath const& baseName = baseSpecifier->name();
@ -415,25 +414,25 @@ void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract)
// "push_front" has the effect that bases mentioned later can overwrite members of bases
// mentioned earlier
input.back().push_front(base);
vector<ContractDefinition const*> const& basesBases = base->annotation().linearizedBaseContracts;
std::vector<ContractDefinition const*> const& basesBases = base->annotation().linearizedBaseContracts;
if (basesBases.empty())
m_errorReporter.fatalTypeError(2449_error, baseName.location(), "Definition of base has to precede definition of derived contract");
input.push_front(list<ContractDefinition const*>(basesBases.begin(), basesBases.end()));
input.push_front(std::list<ContractDefinition const*>(basesBases.begin(), basesBases.end()));
}
input.back().push_front(&_contract);
vector<ContractDefinition const*> result = cThreeMerge(input);
std::vector<ContractDefinition const*> result = cThreeMerge(input);
if (result.empty())
m_errorReporter.fatalTypeError(5005_error, _contract.location(), "Linearization of inheritance graph impossible");
_contract.annotation().linearizedBaseContracts = result;
}
template <class T>
vector<T const*> NameAndTypeResolver::cThreeMerge(list<list<T const*>>& _toMerge)
std::vector<T const*> NameAndTypeResolver::cThreeMerge(std::list<std::list<T const*>>& _toMerge)
{
// returns true iff _candidate appears only as last element of the lists
auto appearsOnlyAtHead = [&](T const* _candidate) -> bool
{
for (list<T const*> const& bases: _toMerge)
for (std::list<T const*> const& bases: _toMerge)
{
solAssert(!bases.empty(), "");
if (find(++bases.begin(), bases.end(), _candidate) != bases.end())
@ -444,7 +443,7 @@ vector<T const*> NameAndTypeResolver::cThreeMerge(list<list<T const*>>& _toMerge
// returns the next candidate to append to the linearized list or nullptr on failure
auto nextCandidate = [&]() -> T const*
{
for (list<T const*> const& bases: _toMerge)
for (std::list<T const*> const& bases: _toMerge)
{
solAssert(!bases.empty(), "");
if (appearsOnlyAtHead(bases.front()))
@ -465,26 +464,26 @@ vector<T const*> NameAndTypeResolver::cThreeMerge(list<list<T const*>>& _toMerge
}
};
_toMerge.remove_if([](list<T const*> const& _bases) { return _bases.empty(); });
vector<T const*> result;
_toMerge.remove_if([](std::list<T const*> const& _bases) { return _bases.empty(); });
std::vector<T const*> result;
while (!_toMerge.empty())
{
T const* candidate = nextCandidate();
if (!candidate)
return vector<T const*>();
return std::vector<T const*>();
result.push_back(candidate);
removeCandidate(candidate);
}
return result;
}
string NameAndTypeResolver::similarNameSuggestions(ASTString const& _name) const
std::string NameAndTypeResolver::similarNameSuggestions(ASTString const& _name) const
{
return util::quotedAlternativesList(m_currentScope->similarNames(_name));
}
DeclarationRegistrationHelper::DeclarationRegistrationHelper(
map<ASTNode const*, shared_ptr<DeclarationContainer>>& _scopes,
std::map<ASTNode const*, std::shared_ptr<DeclarationContainer>>& _scopes,
ASTNode& _astRoot,
ErrorReporter& _errorReporter,
GlobalContext& _globalContext,
@ -502,7 +501,7 @@ DeclarationRegistrationHelper::DeclarationRegistrationHelper(
bool DeclarationRegistrationHelper::registerDeclaration(
DeclarationContainer& _container,
Declaration const& _declaration,
string const* _name,
std::string const* _name,
SourceLocation const* _errorLocation,
bool _inactive,
ErrorReporter& _errorReporter
@ -511,13 +510,13 @@ bool DeclarationRegistrationHelper::registerDeclaration(
if (!_errorLocation)
_errorLocation = &_declaration.location();
string name = _name ? *_name : _declaration.name();
std::string name = _name ? *_name : _declaration.name();
// We use "invisible" for both inactive variables in blocks and for members invisible in contracts.
// They cannot both be true at the same time.
solAssert(!(_inactive && !_declaration.isVisibleInContract()), "");
static set<string> illegalNames{"_", "super", "this"};
static std::set<std::string> illegalNames{"_", "super", "this"};
if (illegalNames.count(name))
{
@ -580,7 +579,7 @@ bool DeclarationRegistrationHelper::visit(SourceUnit& _sourceUnit)
{
if (!m_scopes[&_sourceUnit])
// By importing, it is possible that the container already exists.
m_scopes[&_sourceUnit] = make_shared<DeclarationContainer>(m_currentScope, m_scopes[m_currentScope].get());
m_scopes[&_sourceUnit] = std::make_shared<DeclarationContainer>(m_currentScope, m_scopes[m_currentScope].get());
return ASTVisitor::visit(_sourceUnit);
}
@ -594,7 +593,7 @@ bool DeclarationRegistrationHelper::visit(ImportDirective& _import)
SourceUnit const* importee = _import.annotation().sourceUnit;
solAssert(!!importee, "");
if (!m_scopes[importee])
m_scopes[importee] = make_shared<DeclarationContainer>(nullptr, m_scopes[nullptr].get());
m_scopes[importee] = std::make_shared<DeclarationContainer>(nullptr, m_scopes[nullptr].get());
m_scopes[&_import] = m_scopes[importee];
ASTVisitor::visit(_import);
return false; // Do not recurse into child nodes (Identifier for symbolAliases)
@ -641,7 +640,7 @@ bool DeclarationRegistrationHelper::visitNode(ASTNode& _node)
if (auto* annotation = dynamic_cast<TypeDeclarationAnnotation*>(&_node.annotation()))
{
string canonicalName = dynamic_cast<Declaration const&>(_node).name();
std::string canonicalName = dynamic_cast<Declaration const&>(_node).name();
solAssert(!canonicalName.empty(), "");
for (
@ -684,7 +683,7 @@ void DeclarationRegistrationHelper::enterNewSubScope(ASTNode& _subScope)
{
bool newlyAdded = m_scopes.emplace(
&_subScope,
make_shared<DeclarationContainer>(m_currentScope, m_scopes[m_currentScope].get())
std::make_shared<DeclarationContainer>(m_currentScope, m_scopes[m_currentScope].get())
).second;
solAssert(newlyAdded, "Unable to add new scope.");
}

View File

@ -31,7 +31,6 @@
#include <boost/algorithm/string/predicate.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
using namespace solidity::langutil;
@ -46,7 +45,7 @@ namespace
// Helper struct to do a search by name
struct MatchByName
{
string const& m_name;
std::string const& m_name;
bool operator()(OverrideProxy const& _item)
{
return _item.name() == m_name;
@ -61,7 +60,7 @@ struct MatchByName
*/
struct OverrideGraph
{
OverrideGraph(set<OverrideProxy> const& _baseCallables)
OverrideGraph(std::set<OverrideProxy> const& _baseCallables)
{
for (auto const& baseFunction: _baseCallables)
addEdge(0, visit(baseFunction));
@ -131,17 +130,17 @@ private:
run(vInd, _depth + 1);
if (m_low[vInd] >= m_depths[_u] && m_parent[_u] != -1)
m_cutVertices.insert(m_graph.nodeInv.at(static_cast<int>(_u)));
m_low[_u] = min(m_low[_u], m_low[vInd]);
m_low[_u] = std::min(m_low[_u], m_low[vInd]);
}
else if (v != m_parent[_u])
m_low[_u] = min(m_low[_u], m_depths[vInd]);
m_low[_u] = std::min(m_low[_u], m_depths[vInd]);
}
}
};
vector<ContractDefinition const*> resolveDirectBaseContracts(ContractDefinition const& _contract)
std::vector<ContractDefinition const*> resolveDirectBaseContracts(ContractDefinition const& _contract)
{
vector<ContractDefinition const*> resolvedContracts;
std::vector<ContractDefinition const*> resolvedContracts;
for (ASTPointer<InheritanceSpecifier> const& specifier: _contract.baseContracts())
{
@ -155,7 +154,7 @@ vector<ContractDefinition const*> resolveDirectBaseContracts(ContractDefinition
return resolvedContracts;
}
vector<ASTPointer<IdentifierPath>> sortByContract(vector<ASTPointer<IdentifierPath>> const& _list)
std::vector<ASTPointer<IdentifierPath>> sortByContract(std::vector<ASTPointer<IdentifierPath>> const& _list)
{
auto sorted = _list;
@ -197,17 +196,17 @@ bool OverrideProxy::operator<(OverrideProxy const& _other) const
bool OverrideProxy::isVariable() const
{
return holds_alternative<VariableDeclaration const*>(m_item);
return std::holds_alternative<VariableDeclaration const*>(m_item);
}
bool OverrideProxy::isFunction() const
{
return holds_alternative<FunctionDefinition const*>(m_item);
return std::holds_alternative<FunctionDefinition const*>(m_item);
}
bool OverrideProxy::isModifier() const
{
return holds_alternative<ModifierDefinition const*>(m_item);
return std::holds_alternative<ModifierDefinition const*>(m_item);
}
bool OverrideProxy::CompareBySignature::operator()(OverrideProxy const& _a, OverrideProxy const& _b) const
@ -222,18 +221,18 @@ size_t OverrideProxy::id() const
}, m_item);
}
shared_ptr<OverrideSpecifier> OverrideProxy::overrides() const
std::shared_ptr<OverrideSpecifier> OverrideProxy::overrides() const
{
return std::visit(GenericVisitor{
[&](auto const* _item) { return _item->overrides(); }
}, m_item);
}
set<OverrideProxy> OverrideProxy::baseFunctions() const
std::set<OverrideProxy> OverrideProxy::baseFunctions() const
{
return std::visit(GenericVisitor{
[&](auto const* _item) -> set<OverrideProxy> {
set<OverrideProxy> ret;
[&](auto const* _item) -> std::set<OverrideProxy> {
std::set<OverrideProxy> ret;
for (auto const* f: _item->annotation().baseFunctions)
ret.insert(makeOverrideProxy(*f));
return ret;
@ -256,10 +255,10 @@ void OverrideProxy::storeBaseFunction(OverrideProxy const& _base) const
}, m_item);
}
string const& OverrideProxy::name() const
std::string const& OverrideProxy::name() const
{
return std::visit(GenericVisitor{
[&](auto const* _item) -> string const& { return _item->name(); }
[&](auto const* _item) -> std::string const& { return _item->name(); }
}, m_item);
}
@ -272,7 +271,7 @@ ContractDefinition const& OverrideProxy::contract() const
}, m_item);
}
string const& OverrideProxy::contractName() const
std::string const& OverrideProxy::contractName() const
{
return contract().name();
}
@ -357,7 +356,7 @@ SourceLocation const& OverrideProxy::location() const
}, m_item);
}
string OverrideProxy::astNodeName() const
std::string OverrideProxy::astNodeName() const
{
return std::visit(GenericVisitor{
[&](FunctionDefinition const*) { return "function"; },
@ -366,7 +365,7 @@ string OverrideProxy::astNodeName() const
}, m_item);
}
string OverrideProxy::astNodeNameCapitalized() const
std::string OverrideProxy::astNodeNameCapitalized() const
{
return std::visit(GenericVisitor{
[&](FunctionDefinition const*) { return "Function"; },
@ -375,7 +374,7 @@ string OverrideProxy::astNodeNameCapitalized() const
}, m_item);
}
string OverrideProxy::distinguishingProperty() const
std::string OverrideProxy::distinguishingProperty() const
{
return std::visit(GenericVisitor{
[&](FunctionDefinition const*) { return "name and parameter types"; },
@ -418,10 +417,10 @@ OverrideProxy::OverrideComparator const& OverrideProxy::overrideComparator() con
{
if (!m_comparator)
{
m_comparator = make_shared<OverrideComparator>(std::visit(GenericVisitor{
m_comparator = std::make_shared<OverrideComparator>(std::visit(GenericVisitor{
[&](FunctionDefinition const* _function)
{
vector<string> paramTypes;
std::vector<std::string> paramTypes;
for (Type const* t: externalFunctionType()->parameterTypes())
paramTypes.emplace_back(t->richIdentifier());
return OverrideComparator{
@ -432,7 +431,7 @@ OverrideProxy::OverrideComparator const& OverrideProxy::overrideComparator() con
},
[&](VariableDeclaration const* _var)
{
vector<string> paramTypes;
std::vector<std::string> paramTypes;
for (Type const* t: externalFunctionType()->parameterTypes())
paramTypes.emplace_back(t->richIdentifier());
return OverrideComparator{
@ -674,21 +673,21 @@ void OverrideChecker::checkOverride(OverrideProxy const& _overriding, OverridePr
void OverrideChecker::overrideListError(
OverrideProxy const& _item,
set<ContractDefinition const*, CompareByID> _secondary,
std::set<ContractDefinition const*, CompareByID> _secondary,
ErrorId _error,
string const& _message1,
string const& _message2
std::string const& _message1,
std::string const& _message2
)
{
// Using a set rather than a vector so the order is always the same
set<string> names;
std::set<std::string> names;
SecondarySourceLocation ssl;
for (Declaration const* c: _secondary)
{
ssl.append("This contract: ", c->location());
names.insert("\"" + c->name() + "\"");
}
string contractSingularPlural = "contract ";
std::string contractSingularPlural = "contract ";
if (_secondary.size() > 1)
contractSingularPlural = "contracts ";
@ -708,8 +707,8 @@ void OverrideChecker::overrideError(
OverrideProxy const& _overriding,
OverrideProxy const& _super,
ErrorId _error,
string const& _message,
optional<string> const& _secondaryMsg
std::string const& _message,
std::optional<std::string> const& _secondaryMsg
)
{
m_errorReporter.typeError(
@ -766,7 +765,7 @@ void OverrideChecker::checkAmbiguousOverrides(ContractDefinition const& _contrac
}
}
void OverrideChecker::checkAmbiguousOverridesInternal(set<OverrideProxy> _baseCallables, SourceLocation const& _location) const
void OverrideChecker::checkAmbiguousOverridesInternal(std::set<OverrideProxy> _baseCallables, SourceLocation const& _location) const
{
if (_baseCallables.size() <= 1)
return;
@ -799,17 +798,17 @@ void OverrideChecker::checkAmbiguousOverridesInternal(set<OverrideProxy> _baseCa
for (OverrideProxy const& baseFunction: _baseCallables)
ssl.append("Definition in \"" + baseFunction.contractName() + "\": ", baseFunction.location());
string callableName = _baseCallables.begin()->astNodeName();
std::string callableName = _baseCallables.begin()->astNodeName();
if (_baseCallables.begin()->isVariable())
callableName = "function";
string distinguishigProperty = _baseCallables.begin()->distinguishingProperty();
std::string distinguishigProperty = _baseCallables.begin()->distinguishingProperty();
bool foundVariable = false;
for (auto const& base: _baseCallables)
if (base.isVariable())
foundVariable = true;
string message =
std::string message =
"Derived contract must override " + callableName + " \"" +
_baseCallables.begin()->name() +
"\". Two or more base classes define " + callableName + " with same " + distinguishigProperty + ".";
@ -822,9 +821,9 @@ void OverrideChecker::checkAmbiguousOverridesInternal(set<OverrideProxy> _baseCa
m_errorReporter.typeError(6480_error, _location, ssl, message);
}
set<ContractDefinition const*, OverrideChecker::CompareByID> OverrideChecker::resolveOverrideList(OverrideSpecifier const& _overrides) const
std::set<ContractDefinition const*, OverrideChecker::CompareByID> OverrideChecker::resolveOverrideList(OverrideSpecifier const& _overrides) const
{
set<ContractDefinition const*, CompareByID> resolved;
std::set<ContractDefinition const*, CompareByID> resolved;
for (ASTPointer<IdentifierPath> const& override: _overrides.overrides())
{
@ -842,7 +841,7 @@ set<ContractDefinition const*, OverrideChecker::CompareByID> OverrideChecker::re
void OverrideChecker::checkOverrideList(OverrideProxy _item, OverrideProxyBySignatureMultiSet const& _inherited)
{
set<ContractDefinition const*, CompareByID> specifiedContracts =
std::set<ContractDefinition const*, CompareByID> specifiedContracts =
_item.overrides() ?
resolveOverrideList(*_item.overrides()) :
decltype(specifiedContracts){};
@ -851,7 +850,7 @@ void OverrideChecker::checkOverrideList(OverrideProxy _item, OverrideProxyBySign
if (_item.overrides() && specifiedContracts.size() != _item.overrides()->overrides().size())
{
// Sort by contract id to find duplicate for error reporting
vector<ASTPointer<IdentifierPath>> list =
std::vector<ASTPointer<IdentifierPath>> list =
sortByContract(_item.overrides()->overrides());
// Find duplicates and output error
@ -880,7 +879,7 @@ void OverrideChecker::checkOverrideList(OverrideProxy _item, OverrideProxyBySign
}
}
set<ContractDefinition const*, CompareByID> expectedContracts;
std::set<ContractDefinition const*, CompareByID> expectedContracts;
// Build list of expected contracts
for (auto [begin, end] = _inherited.equal_range(_item); begin != end; begin++)
@ -898,7 +897,7 @@ void OverrideChecker::checkOverrideList(OverrideProxy _item, OverrideProxyBySign
_item.astNodeNameCapitalized() + " has override specified but does not override anything."
);
set<ContractDefinition const*, CompareByID> missingContracts;
std::set<ContractDefinition const*, CompareByID> missingContracts;
// If we expect only one contract, no contract needs to be specified
if (expectedContracts.size() > 1)
missingContracts = expectedContracts - specifiedContracts;
@ -931,7 +930,7 @@ OverrideChecker::OverrideProxyBySignatureMultiSet const& OverrideChecker::inheri
for (auto const* base: resolveDirectBaseContracts(_contract))
{
set<OverrideProxy, OverrideProxy::CompareBySignature> functionsInBase;
std::set<OverrideProxy, OverrideProxy::CompareBySignature> functionsInBase;
for (FunctionDefinition const* fun: base->definedFunctions())
if (!fun->isConstructor())
functionsInBase.emplace(OverrideProxy{fun});
@ -960,7 +959,7 @@ OverrideChecker::OverrideProxyBySignatureMultiSet const& OverrideChecker::inheri
for (auto const* base: resolveDirectBaseContracts(_contract))
{
set<OverrideProxy, OverrideProxy::CompareBySignature> modifiersInBase;
std::set<OverrideProxy, OverrideProxy::CompareBySignature> modifiersInBase;
for (ModifierDefinition const* mod: base->functionModifiers())
modifiersInBase.emplace(OverrideProxy{mod});

View File

@ -27,7 +27,6 @@
#include <memory>
using namespace std;
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -204,7 +203,7 @@ struct ConstStateVarCircularReferenceChecker: public PostTypeChecker::Checker
// Iterating through the dependencies needs to be deterministic and thus cannot
// depend on the memory layout.
// Because of that, we sort by AST node id.
vector<VariableDeclaration const*> dependencies(
std::vector<VariableDeclaration const*> dependencies(
m_constVariableDependencies[&_variable].begin(),
m_constVariableDependencies[&_variable].end()
);
@ -427,10 +426,10 @@ struct ReservedErrorSelector: public PostTypeChecker::Checker
PostTypeChecker::PostTypeChecker(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter)
{
m_checkers.push_back(make_shared<ConstStateVarCircularReferenceChecker>(_errorReporter));
m_checkers.push_back(make_shared<OverrideSpecifierChecker>(_errorReporter));
m_checkers.push_back(make_shared<ModifierContextChecker>(_errorReporter));
m_checkers.push_back(make_shared<EventOutsideEmitErrorOutsideRevertChecker>(_errorReporter));
m_checkers.push_back(make_shared<NoVariablesInInterfaceChecker>(_errorReporter));
m_checkers.push_back(make_shared<ReservedErrorSelector>(_errorReporter));
m_checkers.push_back(std::make_shared<ConstStateVarCircularReferenceChecker>(_errorReporter));
m_checkers.push_back(std::make_shared<OverrideSpecifierChecker>(_errorReporter));
m_checkers.push_back(std::make_shared<ModifierContextChecker>(_errorReporter));
m_checkers.push_back(std::make_shared<EventOutsideEmitErrorOutsideRevertChecker>(_errorReporter));
m_checkers.push_back(std::make_shared<NoVariablesInInterfaceChecker>(_errorReporter));
m_checkers.push_back(std::make_shared<ReservedErrorSelector>(_errorReporter));
}

View File

@ -26,7 +26,6 @@
#include <libsolutil/FunctionSelector.h>
#include <liblangutil/ErrorReporter.h>
using namespace std;
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -48,10 +47,10 @@ bool PostTypeContractLevelChecker::check(ContractDefinition const& _contract)
""
);
map<uint32_t, map<string, SourceLocation>> errorHashes;
std::map<uint32_t, std::map<std::string, SourceLocation>> errorHashes;
for (ErrorDefinition const* error: _contract.interfaceErrors())
{
string signature = error->functionType(true)->externalSignature();
std::string signature = error->functionType(true)->externalSignature();
uint32_t hash = util::selectorFromSignatureU32(signature);
// Fail if there is a different signature for the same hash.
if (!errorHashes[hash].empty() && !errorHashes[hash].count(signature))

View File

@ -39,7 +39,6 @@
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -121,8 +120,8 @@ bool ReferencesResolver::visit(Identifier const& _identifier)
auto declarations = m_resolver.nameFromCurrentScope(_identifier.name());
if (declarations.empty())
{
string suggestions = m_resolver.similarNameSuggestions(_identifier.name());
string errorMessage = "Undeclared identifier.";
std::string suggestions = m_resolver.similarNameSuggestions(_identifier.name());
std::string errorMessage = "Undeclared identifier.";
if (!suggestions.empty())
{
if ("\"" + _identifier.name() + "\"" == suggestions)
@ -192,10 +191,10 @@ bool ReferencesResolver::visit(UsingForDirective const& _usingFor)
// _includeInvisibles is enabled here because external library functions are marked invisible.
// As unintended side-effects other invisible names (eg.: super, this) may be returned as well.
// DeclarationTypeChecker should detect and report such situations.
vector<Declaration const*> declarations = m_resolver.pathFromCurrentScopeWithAllDeclarations(path->path(), true /* _includeInvisibles */);
std::vector<Declaration const*> declarations = m_resolver.pathFromCurrentScopeWithAllDeclarations(path->path(), true /* _includeInvisibles */);
if (declarations.empty())
{
string libraryOrFunctionNameErrorMessage =
std::string libraryOrFunctionNameErrorMessage =
_usingFor.usesBraces() ?
"Identifier is not a function name or not unique." :
"Identifier is not a library name.";
@ -253,9 +252,9 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
{
solAssert(nativeLocationOf(_identifier) == originLocationOf(_identifier), "");
static set<string> suffixes{"slot", "offset", "length", "address", "selector"};
string suffix;
for (string const& s: suffixes)
static std::set<std::string> suffixes{"slot", "offset", "length", "address", "selector"};
std::string suffix;
for (std::string const& s: suffixes)
if (boost::algorithm::ends_with(_identifier.name.str(), "." + s))
suffix = s;
@ -269,7 +268,7 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
if (!declarations.empty())
// the special identifier exists itself, we should not allow that.
return;
string realName = _identifier.name.str().substr(0, _identifier.name.str().size() - suffix.size() - 1);
std::string realName = _identifier.name.str().substr(0, _identifier.name.str().size() - suffix.size() - 1);
solAssert(!realName.empty(), "Empty name.");
declarations = m_resolver.nameFromCurrentScope(realName);
if (!declarations.empty())
@ -350,7 +349,7 @@ void ReferencesResolver::resolveInheritDoc(StructuredDocumentation const& _docum
break;
case 1:
{
string const& name = _annotation.docTags.find("inheritdoc")->second.content;
std::string const& name = _annotation.docTags.find("inheritdoc")->second.content;
if (name.empty())
{
m_errorReporter.docstringParsingError(
@ -361,7 +360,7 @@ void ReferencesResolver::resolveInheritDoc(StructuredDocumentation const& _docum
return;
}
vector<string> path;
std::vector<std::string> path;
boost::split(path, name, boost::is_any_of("."));
if (any_of(path.begin(), path.end(), [](auto& _str) { return _str.empty(); }))
{
@ -421,7 +420,7 @@ void ReferencesResolver::validateYulIdentifierName(yul::YulString _name, SourceL
"User-defined identifiers in inline assembly cannot contain '.'."
);
if (set<string>{"this", "super", "_"}.count(_name.str()))
if (std::set<std::string>{"this", "super", "_"}.count(_name.str()))
m_errorReporter.declarationError(
4113_error,
_location,

View File

@ -20,7 +20,6 @@
#include <libsolidity/ast/AST.h>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;

View File

@ -28,7 +28,6 @@
#include <liblangutil/ErrorReporter.h>
#include <memory>
using namespace std;
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -71,7 +70,7 @@ private:
return m_usesAssembly[&_contract];
}
map<ContractDefinition const*, bool> m_usesAssembly;
std::map<ContractDefinition const*, bool> m_usesAssembly;
};
StaticAnalyzer::StaticAnalyzer(ErrorReporter& _errorReporter):
@ -124,7 +123,7 @@ void StaticAnalyzer::endVisit(FunctionDefinition const&)
5667_error,
var.first.second->location(),
"Unused " +
string(var.first.second->isTryCatchParameter() ? "try/catch" : "function") +
std::string(var.first.second->isTryCatchParameter() ? "try/catch" : "function") +
" parameter. Remove or comment out the variable name to silence this warning."
);
else
@ -142,7 +141,7 @@ bool StaticAnalyzer::visit(Identifier const& _identifier)
{
solAssert(!var->name().empty(), "");
if (var->isLocalVariable())
m_localVarUseCount[make_pair(var->id(), var)] += 1;
m_localVarUseCount[std::make_pair(var->id(), var)] += 1;
}
return true;
}
@ -154,7 +153,7 @@ bool StaticAnalyzer::visit(VariableDeclaration const& _variable)
solAssert(_variable.isLocalVariable(), "");
if (_variable.name() != "")
// This is not a no-op, the entry might pre-exist.
m_localVarUseCount[make_pair(_variable.id(), &_variable)] += 0;
m_localVarUseCount[std::make_pair(_variable.id(), &_variable)] += 0;
}
if (_variable.isStateVariable() || _variable.referenceLocation() == VariableDeclaration::Location::Storage)
@ -162,7 +161,7 @@ bool StaticAnalyzer::visit(VariableDeclaration const& _variable)
for (Type const* type: varType->fullDecomposition())
if (type->storageSizeUpperBound() >= (bigint(1) << 64))
{
string message = "Type " + type->toString(true) +
std::string message = "Type " + type->toString(true) +
" covers a large part of storage and thus makes collisions likely."
" Either use mappings or dynamic arrays and allow their size to be increased only"
" in small quantities per transaction.";
@ -179,7 +178,7 @@ bool StaticAnalyzer::visit(Return const& _return)
if (m_currentFunction && _return.expression())
for (auto const& var: m_currentFunction->returnParameters())
if (!var->name().empty())
m_localVarUseCount[make_pair(var->id(), var.get())] += 1;
m_localVarUseCount[std::make_pair(var->id(), var.get())] += 1;
return true;
}
@ -214,7 +213,7 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess)
else if (type->kind() == MagicType::Kind::MetaType && _memberAccess.memberName() == "runtimeCode")
{
if (!m_constructorUsesAssembly)
m_constructorUsesAssembly = make_unique<ConstructorUsesAssembly>();
m_constructorUsesAssembly = std::make_unique<ConstructorUsesAssembly>();
ContractType const& contract = dynamic_cast<ContractType const&>(*type->typeArgument());
if (m_constructorUsesAssembly->check(contract.contractDefinition()))
m_errorReporter.warning(
@ -288,7 +287,7 @@ bool StaticAnalyzer::visit(InlineAssembly const& _inlineAssembly)
{
solAssert(!var->name().empty(), "");
if (var->isLocalVariable())
m_localVarUseCount[make_pair(var->id(), var)] += 1;
m_localVarUseCount[std::make_pair(var->id(), var)] += 1;
}
}

View File

@ -32,7 +32,6 @@
#include <string>
using namespace std;
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -55,17 +54,17 @@ void SyntaxChecker::endVisit(SourceUnit const& _sourceUnit)
{
if (!m_versionPragmaFound)
{
string errorString("Source file does not specify required compiler version!");
SemVerVersion recommendedVersion{string(VersionString)};
std::string errorString("Source file does not specify required compiler version!");
SemVerVersion recommendedVersion{std::string(VersionString)};
if (!recommendedVersion.isPrerelease())
errorString +=
" Consider adding \"pragma solidity ^" +
to_string(recommendedVersion.major()) +
string(".") +
to_string(recommendedVersion.minor()) +
string(".") +
to_string(recommendedVersion.patch()) +
string(";\"");
std::to_string(recommendedVersion.major()) +
std::string(".") +
std::to_string(recommendedVersion.minor()) +
std::string(".") +
std::to_string(recommendedVersion.patch()) +
std::string(";\"");
// when reporting the warning, print the source name only
m_errorReporter.warning(3420_error, {-1, -1, _sourceUnit.location().sourceName}, errorString);
@ -84,7 +83,7 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma)
else if (_pragma.literals()[0] == "experimental")
{
solAssert(m_sourceUnit, "");
vector<string> literals(_pragma.literals().begin() + 1, _pragma.literals().end());
std::vector<std::string> literals(_pragma.literals().begin() + 1, _pragma.literals().end());
if (literals.empty())
m_errorReporter.syntaxError(
9679_error,
@ -99,7 +98,7 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma)
);
else
{
string const literal = literals[0];
std::string const literal = literals[0];
if (literal.empty())
m_errorReporter.syntaxError(3250_error, _pragma.location(), "Empty experimental feature name is invalid.");
else if (!ExperimentalFeatureNames.count(literal))
@ -135,7 +134,7 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma)
solAssert(m_sourceUnit, "");
if (
_pragma.literals().size() != 2 ||
!set<string>{"v1", "v2"}.count(_pragma.literals()[1])
!std::set<std::string>{"v1", "v2"}.count(_pragma.literals()[1])
)
m_errorReporter.syntaxError(
2745_error,
@ -155,19 +154,12 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma)
{
try
{
vector<Token> tokens(_pragma.tokens().begin() + 1, _pragma.tokens().end());
vector<string> literals(_pragma.literals().begin() + 1, _pragma.literals().end());
std::vector<Token> tokens(_pragma.tokens().begin() + 1, _pragma.tokens().end());
std::vector<std::string> literals(_pragma.literals().begin() + 1, _pragma.literals().end());
SemVerMatchExpressionParser parser(tokens, literals);
SemVerMatchExpression matchExpression = parser.parse();
static SemVerVersion const currentVersion{string(VersionString)};
if (!matchExpression.matches(currentVersion))
m_errorReporter.syntaxError(
3997_error,
_pragma.location(),
"Source file requires different compiler version (current compiler is " +
string(VersionString) + ") - note that nightly builds are considered to be "
"strictly less than the released version"
);
static SemVerVersion const currentVersion{std::string(VersionString)};
solAssert(matchExpression.matches(currentVersion));
m_versionPragmaFound = true;
}
catch (SemVerError const&)
@ -412,7 +404,7 @@ bool SyntaxChecker::visit(UsingForDirective const& _usingFor)
if (!_usingFor.usesBraces())
solAssert(
_usingFor.functionsAndOperators().size() == 1 &&
!get<1>(_usingFor.functionsAndOperators().front())
!std::get<1>(_usingFor.functionsAndOperators().front())
);
if (!m_currentContractKind && !_usingFor.typeName())
@ -455,7 +447,7 @@ bool SyntaxChecker::visit(FunctionDefinition const& _function)
if (!_function.isFree() && !_function.isConstructor() && _function.noVisibilitySpecified())
{
string suggestedVisibility =
std::string suggestedVisibility =
_function.isFallback() ||
_function.isReceive() ||
m_currentContractKind == ContractKind::Interface

View File

@ -51,7 +51,6 @@
#include <memory>
#include <vector>
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::langutil;
@ -205,7 +204,7 @@ void TypeChecker::checkDoubleStorageAssignment(Assignment const& _assignment)
TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall const& _functionCall, bool _abiEncoderV2)
{
vector<ASTPointer<Expression const>> arguments = _functionCall.arguments();
std::vector<ASTPointer<Expression const>> arguments = _functionCall.arguments();
if (arguments.size() != 2)
m_errorReporter.typeError(
5782_error,
@ -296,7 +295,7 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c
TypePointers TypeChecker::typeCheckMetaTypeFunctionAndRetrieveReturnType(FunctionCall const& _functionCall)
{
vector<ASTPointer<Expression const>> arguments = _functionCall.arguments();
std::vector<ASTPointer<Expression const>> arguments = _functionCall.arguments();
if (arguments.size() != 1)
m_errorReporter.fatalTypeError(
8885_error,
@ -442,7 +441,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
m_errorReporter.typeError(5587_error, _function.location(), "\"internal\" and \"private\" functions cannot be payable.");
}
vector<VariableDeclaration const*> internalParametersInConstructor;
std::vector<VariableDeclaration const*> internalParametersInConstructor;
auto checkArgumentAndReturnParameter = [&](VariableDeclaration const& _var) {
if (type(_var)->containsNestedMapping())
@ -472,7 +471,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
if (!iType)
{
string message = iType.message();
std::string message = iType.message();
solAssert(!message.empty(), "Expected detailed error message!");
if (_function.isConstructor())
message += " You can make the contract abstract to avoid this problem.";
@ -483,7 +482,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
!typeSupportedByOldABIEncoder(*type(_var), _function.libraryFunction())
)
{
string message =
std::string message =
"This type is only supported in ABI coder v2. "
"Use \"pragma abicoder v2;\" to enable the feature.";
if (_function.isConstructor())
@ -509,10 +508,10 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
var->accept(*this);
}
set<Declaration const*> modifiers;
std::set<Declaration const*> modifiers;
for (ASTPointer<ModifierInvocation> const& modifier: _function.modifiers())
{
vector<ContractDefinition const*> baseContracts;
std::vector<ContractDefinition const*> baseContracts;
if (auto contract = dynamic_cast<ContractDefinition const*>(_function.scope()))
{
baseContracts = contract->annotation().linearizedBaseContracts;
@ -522,7 +521,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
visitManually(
*modifier,
_function.isConstructor() ? baseContracts : vector<ContractDefinition const*>()
_function.isConstructor() ? baseContracts : std::vector<ContractDefinition const*>()
);
Declaration const* decl = &dereference(modifier->name());
if (modifiers.count(decl))
@ -642,7 +641,7 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
FunctionType getter(_variable);
if (!useABICoderV2())
{
vector<string> unsupportedTypes;
std::vector<std::string> unsupportedTypes;
for (auto const& param: getter.parameterTypes() + getter.returnParameterTypes())
if (!typeSupportedByOldABIEncoder(*param, false /* isLibrary */))
unsupportedTypes.emplace_back(param->humanReadableName());
@ -713,7 +712,7 @@ void TypeChecker::endVisit(StructDefinition const& _struct)
void TypeChecker::visitManually(
ModifierInvocation const& _modifier,
vector<ContractDefinition const*> const& _bases
std::vector<ContractDefinition const*> const& _bases
)
{
std::vector<ASTPointer<Expression>> const& arguments =
@ -724,8 +723,8 @@ void TypeChecker::visitManually(
_modifier.name().accept(*this);
auto const* declaration = &dereference(_modifier.name());
vector<ASTPointer<VariableDeclaration>> emptyParameterList;
vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr;
std::vector<ASTPointer<VariableDeclaration>> emptyParameterList;
std::vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr;
if (auto modifierDecl = dynamic_cast<ModifierDefinition const*>(declaration))
{
parameters = &modifierDecl->parameters();
@ -920,8 +919,8 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
if (!identifierInfo.suffix.empty())
{
string const& suffix = identifierInfo.suffix;
solAssert((set<string>{"offset", "slot", "length", "selector", "address"}).count(suffix), "");
std::string const& suffix = identifierInfo.suffix;
solAssert((std::set<std::string>{"offset", "slot", "length", "selector", "address"}).count(suffix), "");
if (!var->isConstant() && (var->isStateVariable() || var->type()->dataStoredIn(DataLocation::Storage)))
{
if (suffix != "slot" && suffix != "offset")
@ -1042,7 +1041,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
return true;
};
solAssert(!_inlineAssembly.annotation().analysisInfo, "");
_inlineAssembly.annotation().analysisInfo = make_shared<yul::AsmAnalysisInfo>();
_inlineAssembly.annotation().analysisInfo = std::make_shared<yul::AsmAnalysisInfo>();
yul::AsmAnalyzer analyzer(
*_inlineAssembly.annotation().analysisInfo,
m_errorReporter,
@ -1113,9 +1112,9 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement)
2800_error,
successClause.location(),
"Function returns " +
to_string(functionType.returnParameterTypes().size()) +
std::to_string(functionType.returnParameterTypes().size()) +
" values, but returns clause has " +
to_string(parameters.size()) +
std::to_string(parameters.size()) +
" variables."
);
for (auto&& [parameter, returnType]: ranges::views::zip(parameters, returnTypes))
@ -1363,7 +1362,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
else
valueTypes = TypePointers{type(*_statement.initialValue())};
vector<ASTPointer<VariableDeclaration>> const& variables = _statement.declarations();
std::vector<ASTPointer<VariableDeclaration>> const& variables = _statement.declarations();
if (variables.empty())
// We already have an error for this in the SyntaxChecker.
solAssert(m_errorReporter.hasErrors(), "");
@ -1378,7 +1377,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
")."
);
for (size_t i = 0; i < min(variables.size(), valueTypes.size()); ++i)
for (size_t i = 0; i < std::min(variables.size(), valueTypes.size()); ++i)
{
if (!variables[i])
continue;
@ -1535,14 +1534,14 @@ void TypeChecker::checkExpressionAssignment(Type const& _type, Expression const&
m_errorReporter.typeError(5547_error, _expression.location(), "Empty tuple on the left hand side.");
auto const* tupleType = dynamic_cast<TupleType const*>(&_type);
auto const& types = tupleType && tupleExpression->components().size() != 1 ? tupleType->components() : vector<Type const*> { &_type };
auto const& types = tupleType && tupleExpression->components().size() != 1 ? tupleType->components() : std::vector<Type const*> { &_type };
solAssert(
tupleExpression->components().size() == types.size() || m_errorReporter.hasErrors(),
"Array sizes don't match and no errors generated."
);
for (size_t i = 0; i < min(tupleExpression->components().size(), types.size()); i++)
for (size_t i = 0; i < std::min(tupleExpression->components().size(), types.size()); i++)
if (types[i])
{
solAssert(!!tupleExpression->components()[i], "");
@ -1607,7 +1606,7 @@ bool TypeChecker::visit(Assignment const& _assignment)
7366_error,
_assignment.location(),
"Operator " +
string(TokenTraits::friendlyName(_assignment.assignmentOperator())) +
std::string(TokenTraits::friendlyName(_assignment.assignmentOperator())) +
" not compatible with types " +
t->humanReadableName() +
" and " +
@ -1621,7 +1620,7 @@ bool TypeChecker::visit(Assignment const& _assignment)
bool TypeChecker::visit(TupleExpression const& _tuple)
{
_tuple.annotation().isConstant = false;
vector<ASTPointer<Expression>> const& components = _tuple.components();
std::vector<ASTPointer<Expression>> const& components = _tuple.components();
TypePointers types;
if (_tuple.annotation().willBeWrittenTo)
@ -1734,7 +1733,7 @@ bool TypeChecker::visit(UnaryOperation const& _operation)
// Check if the operator is built-in or user-defined.
TypeResult builtinResult = operandType->unaryOperatorResult(op);
set<FunctionDefinition const*, ASTNode::CompareByID> matchingDefinitions = operandType->operatorDefinitions(
std::set<FunctionDefinition const*, ASTNode::CompareByID> matchingDefinitions = operandType->operatorDefinitions(
op,
*currentDefinitionScope(),
true // _unary
@ -1760,7 +1759,7 @@ bool TypeChecker::visit(UnaryOperation const& _operation)
}
else
{
string description = fmt::format(
std::string description = fmt::format(
"Built-in unary operator {} cannot be applied to type {}.",
TokenTraits::friendlyName(op),
operandType->humanReadableName()
@ -1802,7 +1801,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
// Check if the operator is built-in or user-defined.
TypeResult builtinResult = leftType->binaryOperatorResult(_operation.getOperator(), rightType);
set<FunctionDefinition const*, ASTNode::CompareByID> matchingDefinitions = leftType->operatorDefinitions(
std::set<FunctionDefinition const*, ASTNode::CompareByID> matchingDefinitions = leftType->operatorDefinitions(
_operation.getOperator(),
*currentDefinitionScope(),
false // _unary
@ -1828,7 +1827,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
}
else
{
string description = fmt::format(
std::string description = fmt::format(
"Built-in binary operator {} cannot be applied to types {} and {}.",
TokenTraits::friendlyName(_operation.getOperator()),
leftType->humanReadableName(),
@ -1893,7 +1892,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
if (_operation.getOperator() == Token::Exp || _operation.getOperator() == Token::SHL)
{
string operation = _operation.getOperator() == Token::Exp ? "exponentiation" : "shift";
std::string operation = _operation.getOperator() == Token::Exp ? "exponentiation" : "shift";
if (
leftType->category() == Type::Category::RationalNumber &&
rightType->category() != Type::Category::RationalNumber
@ -1933,7 +1932,7 @@ Type const* TypeChecker::typeCheckTypeConversionAndRetrieveReturnType(
solAssert(*_functionCall.annotation().kind == FunctionCallKind::TypeConversion, "");
Type const* expressionType = type(_functionCall.expression());
vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();
std::vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();
bool const isPositionalCall = _functionCall.names().empty();
Type const* resultType = dynamic_cast<TypeType const&>(*expressionType).actualType();
@ -2215,7 +2214,7 @@ void TypeChecker::typeCheckABIEncodeFunctions(
}
// Check additional arguments for variadic functions
vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();
std::vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();
for (size_t i = 0; i < arguments.size(); ++i)
{
auto const& argType = type(*arguments[i]);
@ -2274,7 +2273,7 @@ void TypeChecker::typeCheckABIEncodeFunctions(
void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCall)
{
vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();
std::vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();
// Expecting first argument to be the function pointer and second to be a tuple.
if (arguments.size() != 2)
@ -2311,7 +2310,7 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
externalFunctionType->kind() != FunctionType::Kind::Declaration
)
{
string msg = "Expected regular external function type, or external view on public function.";
std::string msg = "Expected regular external function type, or external view on public function.";
switch (externalFunctionType->kind())
{
@ -2360,7 +2359,7 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
}
solAssert(!externalFunctionType->takesArbitraryParameters(), "Function must have fixed parameters.");
// Tuples with only one component become that component
vector<ASTPointer<Expression const>> callArguments;
std::vector<ASTPointer<Expression const>> callArguments;
auto const* tupleType = dynamic_cast<TupleType const*>(type(*arguments[1]));
if (tupleType)
@ -2387,9 +2386,9 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
7788_error,
_functionCall.location(),
"Expected " +
to_string(externalFunctionType->parameterTypes().size()) +
std::to_string(externalFunctionType->parameterTypes().size()) +
" instead of " +
to_string(callArguments.size()) +
std::to_string(callArguments.size()) +
" components for the tuple parameter."
);
else
@ -2397,13 +2396,13 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
7515_error,
_functionCall.location(),
"Expected a tuple with " +
to_string(externalFunctionType->parameterTypes().size()) +
std::to_string(externalFunctionType->parameterTypes().size()) +
" components instead of a single non-tuple parameter."
);
}
// Use min() to check as much as we can before failing fatally
size_t const numParameters = min(callArguments.size(), externalFunctionType->parameterTypes().size());
size_t const numParameters = std::min(callArguments.size(), externalFunctionType->parameterTypes().size());
for (size_t i = 0; i < numParameters; i++)
{
@ -2414,7 +2413,7 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
5407_error,
callArguments[i]->location(),
"Cannot implicitly convert component at position " +
to_string(i) +
std::to_string(i) +
" from \"" +
argType.humanReadableName() +
"\" to \"" +
@ -2437,7 +2436,7 @@ void TypeChecker::typeCheckStringConcatFunction(
typeCheckFunctionGeneralChecks(_functionCall, _functionType);
for (shared_ptr<Expression const> const& argument: _functionCall.arguments())
for (std::shared_ptr<Expression const> const& argument: _functionCall.arguments())
{
Type const* argumentType = type(*argument);
bool notConvertibleToString = !argumentType->isImplicitlyConvertibleTo(*TypeProvider::stringMemory());
@ -2464,7 +2463,7 @@ void TypeChecker::typeCheckBytesConcatFunction(
typeCheckFunctionGeneralChecks(_functionCall, _functionType);
for (shared_ptr<Expression const> const& argument: _functionCall.arguments())
for (std::shared_ptr<Expression const> const& argument: _functionCall.arguments())
{
Type const* argumentType = type(*argument);
bool notConvertibleToBytes =
@ -2504,8 +2503,8 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
);
TypePointers const& parameterTypes = _functionType->parameterTypes();
vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();
vector<ASTPointer<ASTString>> const& argumentNames = _functionCall.names();
std::vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();
std::vector<ASTPointer<ASTString>> const& argumentNames = _functionCall.names();
// Check number of passed in arguments
if (
@ -2516,22 +2515,22 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
bool const isStructConstructorCall =
functionCallKind == FunctionCallKind::StructConstructorCall;
auto [errorId, description] = [&]() -> tuple<ErrorId, string> {
string msg = isVariadic ?
auto [errorId, description] = [&]() -> std::tuple<ErrorId, std::string> {
std::string msg = isVariadic ?
"Need at least " +
toString(parameterTypes.size()) +
" arguments for " +
string(isStructConstructorCall ? "struct constructor" : "function call") +
std::string(isStructConstructorCall ? "struct constructor" : "function call") +
", but provided only " +
toString(arguments.size()) +
"."
:
"Wrong argument count for " +
string(isStructConstructorCall ? "struct constructor" : "function call") +
std::string(isStructConstructorCall ? "struct constructor" : "function call") +
": " +
toString(arguments.size()) +
" arguments given but " +
string(isVariadic ? "need at least " : "expected ") +
std::string(isVariadic ? "need at least " : "expected ") +
toString(parameterTypes.size()) +
".";
@ -2659,8 +2658,8 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
BoolResult result = type(*paramArgMap[i])->isImplicitlyConvertibleTo(*parameterTypes[i]);
if (!result)
{
auto [errorId, description] = [&]() -> tuple<ErrorId, string> {
string msg =
auto [errorId, description] = [&]() -> std::tuple<ErrorId, std::string> {
std::string msg =
"Invalid type for argument in function call. "
"Invalid implicit conversion from " +
type(*paramArgMap[i])->humanReadableName() +
@ -2751,7 +2750,7 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
bool TypeChecker::visit(FunctionCall const& _functionCall)
{
vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();
std::vector<ASTPointer<Expression const>> const& arguments = _functionCall.arguments();
bool argumentsArePure = true;
// We need to check arguments' type first as they will be needed for overload resolution.
@ -2991,7 +2990,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions)
"{...}-option."
);
auto setCheckOption = [&](bool& _option, string const& _name)
auto setCheckOption = [&](bool& _option, std::string const& _name)
{
if (_option)
m_errorReporter.typeError(
@ -3005,7 +3004,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions)
for (size_t i = 0; i < _functionCallOptions.names().size(); ++i)
{
string const& name = *(_functionCallOptions.names()[i]);
std::string const& name = *(_functionCallOptions.names()[i]);
if (name == "salt")
{
if (kind == FunctionType::Kind::Creation)
@ -3185,8 +3184,8 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
);
}
auto [errorId, description] = [&]() -> tuple<ErrorId, string> {
string errorMsg = "Member \"" + memberName + "\" not found or not visible "
auto [errorId, description] = [&]() -> std::tuple<ErrorId, std::string> {
std::string errorMsg = "Member \"" + memberName + "\" not found or not visible "
"after argument-dependent lookup in " + exprType->humanReadableName() + ".";
if (auto const* funType = dynamic_cast<FunctionType const*>(exprType))
@ -3222,7 +3221,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
if (addressMember.name == memberName)
{
auto const* var = dynamic_cast<Identifier const*>(&_memberAccess.expression());
string varName = var ? var->name() : "...";
std::string varName = var ? var->name() : "...";
errorMsg += " Use \"address(" + varName + ")." + memberName + "\" to access this address member.";
return { 3125_error, errorMsg };
}
@ -3606,13 +3605,13 @@ bool TypeChecker::visit(IndexRangeAccess const& _access)
return false;
}
vector<Declaration const*> TypeChecker::cleanOverloadedDeclarations(
std::vector<Declaration const*> TypeChecker::cleanOverloadedDeclarations(
Identifier const& _identifier,
vector<Declaration const*> const& _candidates
std::vector<Declaration const*> const& _candidates
)
{
solAssert(_candidates.size() > 1, "");
vector<Declaration const*> uniqueDeclarations;
std::vector<Declaration const*> uniqueDeclarations;
for (Declaration const* declaration: _candidates)
{
@ -3665,7 +3664,7 @@ bool TypeChecker::visit(Identifier const& _identifier)
else if (!annotation.arguments)
{
// The identifier should be a public state variable shadowing other functions
vector<Declaration const*> candidates;
std::vector<Declaration const*> candidates;
for (Declaration const* declaration: annotation.overloadedDeclarations)
{
@ -3681,7 +3680,7 @@ bool TypeChecker::visit(Identifier const& _identifier)
}
else
{
vector<Declaration const*> candidates;
std::vector<Declaration const*> candidates;
for (Declaration const* declaration: annotation.overloadedDeclarations)
{
@ -3700,7 +3699,7 @@ bool TypeChecker::visit(Identifier const& _identifier)
if (!declaration->location().isValid())
{
// Try to re-construct function definition
string description;
std::string description;
for (auto const& param: declaration->functionType(true)->parameterTypes())
description += (description.empty() ? "" : ", ") + param->humanReadableName();
description = "function " + _identifier.name() + "(" + description + ")";
@ -3816,12 +3815,12 @@ void TypeChecker::endVisit(Literal const& _literal)
// Assign type here if it even looks like an address. This prevents double errors for invalid addresses
_literal.annotation().type = TypeProvider::address();
string msg;
std::string msg;
if (_literal.valueWithoutUnderscores().length() != 42) // "0x" + 40 hex digits
// looksLikeAddress enforces that it is a hex literal starting with "0x"
msg =
"This looks like an address but is not exactly 40 hex digits. It is " +
to_string(_literal.valueWithoutUnderscores().length() - 2) +
std::to_string(_literal.valueWithoutUnderscores().length() - 2) +
" hex digits.";
else if (!_literal.passesAddressChecksum())
{
@ -4034,7 +4033,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
bool isBinaryOnlyOperator = (TokenTraits::isBinaryOp(operator_.value()) && !TokenTraits::isUnaryOp(operator_.value()));
bool firstParameterMatchesUsingFor = parameterCount == 0 || *usingForType == *parameterTypes.front();
optional<string> wrongParametersMessage;
std::optional<std::string> wrongParametersMessage;
if (isBinaryOnlyOperator && (parameterCount != 2 || !identicalFirstTwoParameters))
wrongParametersMessage = fmt::format("two parameters of type {} and the same data location", usingForType->canonicalName());
else if (isUnaryOnlyOperator && (parameterCount != 1 || !firstParameterMatchesUsingFor))
@ -4065,7 +4064,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
TypePointers const& returnParameterTypes = functionType->returnParameterTypes();
size_t const returnParameterCount = returnParameterTypes.size();
optional<string> wrongReturnParametersMessage;
std::optional<std::string> wrongReturnParametersMessage;
if (!TokenTraits::isCompareOp(operator_.value()) && operator_.value() != Token::Not)
{
if (returnParameterCount != 1 || *usingForType != *returnParameterTypes.front())
@ -4100,7 +4099,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
{
// TODO: This is pretty inefficient. For every operator binding we find, we're
// traversing all bindings in all `using for` directives in the current scope.
set<FunctionDefinition const*, ASTNode::CompareByID> matchingDefinitions = usingForType->operatorDefinitions(
std::set<FunctionDefinition const*, ASTNode::CompareByID> matchingDefinitions = usingForType->operatorDefinitions(
operator_.value(),
*currentDefinitionScope(),
parameterCount == 1 // _unary
@ -4133,7 +4132,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
void TypeChecker::checkErrorAndEventParameters(CallableDeclaration const& _callable)
{
string kind = dynamic_cast<EventDefinition const*>(&_callable) ? "event" : "error";
std::string kind = dynamic_cast<EventDefinition const*>(&_callable) ? "event" : "error";
for (ASTPointer<VariableDeclaration> const& var: _callable.parameters())
{
if (type(*var)->containsNestedMapping())
@ -4223,7 +4222,7 @@ void TypeChecker::requireLValue(Expression const& _expression, bool _ordinaryAss
if (*_expression.annotation().isLValue)
return;
auto [errorId, description] = [&]() -> tuple<ErrorId, string> {
auto [errorId, description] = [&]() -> std::tuple<ErrorId, std::string> {
if (*_expression.annotation().isConstant)
return { 6520_error, "Cannot assign to a constant variable." };

View File

@ -27,7 +27,6 @@
#include <utility>
#include <variant>
using namespace std;
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -312,13 +311,13 @@ ViewPureChecker::MutabilityAndLocation const& ViewPureChecker::modifierMutabilit
{
MutabilityAndLocation bestMutabilityAndLocation{};
FunctionDefinition const* currentFunction = nullptr;
swap(bestMutabilityAndLocation, m_bestMutabilityAndLocation);
swap(currentFunction, m_currentFunction);
std::swap(bestMutabilityAndLocation, m_bestMutabilityAndLocation);
std::swap(currentFunction, m_currentFunction);
_modifier.accept(*this);
swap(bestMutabilityAndLocation, m_bestMutabilityAndLocation);
swap(currentFunction, m_currentFunction);
std::swap(bestMutabilityAndLocation, m_bestMutabilityAndLocation);
std::swap(currentFunction, m_currentFunction);
}
return m_inferredMutability.at(&_modifier);
}
@ -384,8 +383,8 @@ void ViewPureChecker::endVisit(MemberAccess const& _memberAccess)
break;
case Type::Category::Magic:
{
using MagicMember = pair<MagicType::Kind, string>;
set<MagicMember> static const pureMembers{
using MagicMember = std::pair<MagicType::Kind, std::string>;
std::set<MagicMember> static const pureMembers{
{MagicType::Kind::ABI, "decode"},
{MagicType::Kind::ABI, "encode"},
{MagicType::Kind::ABI, "encodePacked"},
@ -401,7 +400,7 @@ void ViewPureChecker::endVisit(MemberAccess const& _memberAccess)
{MagicType::Kind::MetaType, "min"},
{MagicType::Kind::MetaType, "max"},
};
set<MagicMember> static const payableMembers{
std::set<MagicMember> static const payableMembers{
{MagicType::Kind::Message, "value"}
};

View File

@ -39,13 +39,12 @@
#include <functional>
#include <utility>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
namespace
{
TryCatchClause const* findClause(vector<ASTPointer<TryCatchClause>> const& _clauses, optional<string> _errorName = {})
TryCatchClause const* findClause(std::vector<ASTPointer<TryCatchClause>> const& _clauses, std::optional<std::string> _errorName = {})
{
for (auto const& clause: ranges::views::tail(_clauses))
if (_errorName.has_value() ? clause->errorName() == _errorName : clause->errorName().empty())
@ -119,7 +118,7 @@ FunctionDefinition const* ASTNode::resolveFunctionCall(FunctionCall const& _func
ASTAnnotation& ASTNode::annotation() const
{
if (!m_annotation)
m_annotation = make_unique<ASTAnnotation>();
m_annotation = std::make_unique<ASTAnnotation>();
return *m_annotation;
}
@ -128,9 +127,9 @@ SourceUnitAnnotation& SourceUnit::annotation() const
return initAnnotation<SourceUnitAnnotation>();
}
set<SourceUnit const*> SourceUnit::referencedSourceUnits(bool _recurse, set<SourceUnit const*> _skipList) const
std::set<SourceUnit const*> SourceUnit::referencedSourceUnits(bool _recurse, std::set<SourceUnit const*> _skipList) const
{
set<SourceUnit const*> sourceUnits;
std::set<SourceUnit const*> sourceUnits;
for (ImportDirective const* importDirective: filteredNodes<ImportDirective>(nodes()))
{
auto const& sourceUnit = importDirective->annotation().sourceUnit;
@ -161,11 +160,11 @@ bool ContractDefinition::derivesFrom(ContractDefinition const& _base) const
return util::contains(annotation().linearizedBaseContracts, &_base);
}
map<util::FixedHash<4>, FunctionTypePointer> ContractDefinition::interfaceFunctions(bool _includeInheritedFunctions) const
std::map<util::FixedHash<4>, FunctionTypePointer> ContractDefinition::interfaceFunctions(bool _includeInheritedFunctions) const
{
auto exportedFunctionList = interfaceFunctionList(_includeInheritedFunctions);
map<util::FixedHash<4>, FunctionTypePointer> exportedFunctions;
std::map<util::FixedHash<4>, FunctionTypePointer> exportedFunctions;
for (auto const& it: exportedFunctionList)
exportedFunctions.insert(it);
@ -208,11 +207,11 @@ FunctionDefinition const* ContractDefinition::receiveFunction() const
return nullptr;
}
vector<EventDefinition const*> const& ContractDefinition::definedInterfaceEvents() const
std::vector<EventDefinition const*> const& ContractDefinition::definedInterfaceEvents() const
{
return m_interfaceEvents.init([&]{
set<string> eventsSeen;
vector<EventDefinition const*> interfaceEvents;
std::set<std::string> eventsSeen;
std::vector<EventDefinition const*> interfaceEvents;
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
for (EventDefinition const* e: contract->events())
@ -222,7 +221,7 @@ vector<EventDefinition const*> const& ContractDefinition::definedInterfaceEvents
/// and not to function encoding (jump vs. call)
FunctionType const* functionType = e->functionType(true);
solAssert(functionType, "");
string eventSignature = functionType->externalSignature();
std::string eventSignature = functionType->externalSignature();
if (eventsSeen.count(eventSignature) == 0)
{
eventsSeen.insert(eventSignature);
@ -233,7 +232,7 @@ vector<EventDefinition const*> const& ContractDefinition::definedInterfaceEvents
});
}
vector<EventDefinition const*> const ContractDefinition::usedInterfaceEvents() const
std::vector<EventDefinition const*> const ContractDefinition::usedInterfaceEvents() const
{
solAssert(annotation().creationCallGraph.set(), "");
@ -243,9 +242,9 @@ vector<EventDefinition const*> const ContractDefinition::usedInterfaceEvents() c
);
}
vector<EventDefinition const*> ContractDefinition::interfaceEvents(bool _requireCallGraph) const
std::vector<EventDefinition const*> ContractDefinition::interfaceEvents(bool _requireCallGraph) const
{
set<EventDefinition const*, CompareByID> result;
std::set<EventDefinition const*, CompareByID> result;
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
result += contract->events();
solAssert(annotation().creationCallGraph.set() == annotation().deployedCallGraph.set());
@ -255,12 +254,12 @@ vector<EventDefinition const*> ContractDefinition::interfaceEvents(bool _require
result += usedInterfaceEvents();
// We could filter out all events that do not have an external interface
// if _requireCallGraph is false.
return util::convertContainer<vector<EventDefinition const*>>(std::move(result));
return util::convertContainer<std::vector<EventDefinition const*>>(std::move(result));
}
vector<ErrorDefinition const*> ContractDefinition::interfaceErrors(bool _requireCallGraph) const
std::vector<ErrorDefinition const*> ContractDefinition::interfaceErrors(bool _requireCallGraph) const
{
set<ErrorDefinition const*, CompareByID> result;
std::set<ErrorDefinition const*, CompareByID> result;
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
result += filteredNodes<ErrorDefinition>(contract->m_subNodes);
solAssert(annotation().creationCallGraph.set() == annotation().deployedCallGraph.set(), "");
@ -270,20 +269,20 @@ vector<ErrorDefinition const*> ContractDefinition::interfaceErrors(bool _require
result +=
(*annotation().creationCallGraph)->usedErrors +
(*annotation().deployedCallGraph)->usedErrors;
return util::convertContainer<vector<ErrorDefinition const*>>(std::move(result));
return util::convertContainer<std::vector<ErrorDefinition const*>>(std::move(result));
}
vector<pair<util::FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::interfaceFunctionList(bool _includeInheritedFunctions) const
std::vector<std::pair<util::FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::interfaceFunctionList(bool _includeInheritedFunctions) const
{
return m_interfaceFunctionList[_includeInheritedFunctions].init([&]{
set<string> signaturesSeen;
vector<pair<util::FixedHash<4>, FunctionTypePointer>> interfaceFunctionList;
std::set<std::string> signaturesSeen;
std::vector<std::pair<util::FixedHash<4>, FunctionTypePointer>> interfaceFunctionList;
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
{
if (_includeInheritedFunctions == false && contract != this)
continue;
vector<FunctionTypePointer> functions;
std::vector<FunctionTypePointer> functions;
for (FunctionDefinition const* f: contract->definedFunctions())
if (f->isPartOfExternalInterface())
functions.push_back(TypeProvider::function(*f, FunctionType::Kind::External));
@ -295,7 +294,7 @@ vector<pair<util::FixedHash<4>, FunctionTypePointer>> const& ContractDefinition:
if (!fun->interfaceFunctionType())
// Fails hopefully because we already registered the error
continue;
string functionSignature = fun->externalSignature();
std::string functionSignature = fun->externalSignature();
if (signaturesSeen.count(functionSignature) == 0)
{
signaturesSeen.insert(functionSignature);
@ -357,7 +356,7 @@ FunctionDefinition const* ContractDefinition::nextConstructor(ContractDefinition
return nullptr;
}
multimap<std::string, FunctionDefinition const*> const& ContractDefinition::definedFunctionsByName() const
std::multimap<std::string, FunctionDefinition const*> const& ContractDefinition::definedFunctionsByName() const
{
return m_definedFunctionsByName.init([&]{
std::multimap<std::string, FunctionDefinition const*> result;
@ -386,7 +385,7 @@ TypeDeclarationAnnotation& UserDefinedValueTypeDefinition::annotation() const
std::vector<std::pair<ASTPointer<IdentifierPath>, std::optional<Token>>> UsingForDirective::functionsAndOperators() const
{
return ranges::zip_view(m_functionsOrLibrary, m_operators) | ranges::to<vector>;
return ranges::zip_view(m_functionsOrLibrary, m_operators) | ranges::to<std::vector>;
}
Type const* StructDefinition::type() const
@ -484,12 +483,12 @@ Type const* FunctionDefinition::typeViaContractName() const
return TypeProvider::function(*this, FunctionType::Kind::Declaration);
}
string FunctionDefinition::externalSignature() const
std::string FunctionDefinition::externalSignature() const
{
return TypeProvider::function(*this)->externalSignature();
}
string FunctionDefinition::externalIdentifierHex() const
std::string FunctionDefinition::externalIdentifierHex() const
{
return TypeProvider::function(*this)->externalIdentifierHex();
}
@ -639,7 +638,7 @@ CallableDeclaration const* Scopable::functionOrModifierDefinition() const
return nullptr;
}
string Scopable::sourceUnitName() const
std::string Scopable::sourceUnitName() const
{
return *sourceUnit().annotation().path;
}
@ -701,7 +700,7 @@ bool VariableDeclaration::isCallableOrCatchParameter() const
if (isReturnParameter() || isTryCatchParameter())
return true;
vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr;
std::vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr;
if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
parameters = &funTypeName->parameterTypes();
@ -722,7 +721,7 @@ bool VariableDeclaration::isLocalOrReturn() const
bool VariableDeclaration::isReturnParameter() const
{
vector<ASTPointer<VariableDeclaration>> const* returnParameters = nullptr;
std::vector<ASTPointer<VariableDeclaration>> const* returnParameters = nullptr;
if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
returnParameters = &funTypeName->returnParameterTypes();
@ -813,15 +812,15 @@ bool VariableDeclaration::isFileLevelVariable() const
return dynamic_cast<SourceUnit const*>(scope());
}
set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() const
std::set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() const
{
using Location = VariableDeclaration::Location;
if (!hasReferenceOrMappingType() || isStateVariable() || isEventOrErrorParameter())
return set<Location>{ Location::Unspecified };
return std::set<Location>{ Location::Unspecified };
else if (isCallableOrCatchParameter())
{
set<Location> locations{ Location::Memory };
std::set<Location> locations{ Location::Memory };
if (
isConstructorParameter() ||
isInternalCallableParameter() ||
@ -835,13 +834,13 @@ set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() c
}
else if (isLocalVariable())
// Further restrictions will be imposed later on.
return set<Location>{ Location::Memory, Location::Storage, Location::CallData };
return std::set<Location>{ Location::Memory, Location::Storage, Location::CallData };
else
// Struct members etc.
return set<Location>{ Location::Unspecified };
return std::set<Location>{ Location::Unspecified };
}
string VariableDeclaration::externalIdentifierHex() const
std::string VariableDeclaration::externalIdentifierHex() const
{
solAssert(isStateVariable() && isPublic(), "Can only be called for public state variables");
return TypeProvider::function(*this)->externalIdentifierHex();
@ -958,7 +957,7 @@ FunctionCallAnnotation& FunctionCall::annotation() const
return initAnnotation<FunctionCallAnnotation>();
}
vector<ASTPointer<Expression const>> FunctionCall::sortedArguments() const
std::vector<ASTPointer<Expression const>> FunctionCall::sortedArguments() const
{
// normal arguments
if (m_names.empty())
@ -975,7 +974,7 @@ vector<ASTPointer<Expression const>> FunctionCall::sortedArguments() const
else
functionType = dynamic_cast<FunctionType const*>(m_expression->annotation().type);
vector<ASTPointer<Expression const>> sorted;
std::vector<ASTPointer<Expression const>> sorted;
for (auto const& parameterName: functionType->parameterNames())
{
bool found = false;
@ -1030,13 +1029,13 @@ bool Literal::passesAddressChecksum() const
return util::passesAddressChecksum(valueWithoutUnderscores(), true);
}
string Literal::getChecksummedAddress() const
std::string Literal::getChecksummedAddress() const
{
solAssert(isHexNumber(), "Expected hex number");
/// Pad literal to be a proper hex address.
string address = valueWithoutUnderscores().substr(2);
std::string address = valueWithoutUnderscores().substr(2);
if (address.length() > 40)
return string();
return std::string();
address.insert(address.begin(), 40 - address.size(), '0');
return util::getChecksummedAddress(address);
}

View File

@ -87,16 +87,20 @@ public:
static void listAccept(std::vector<T> const& _list, ASTVisitor& _visitor)
{
for (T const& element: _list)
if (element)
{
solAssert(element);
element->accept(_visitor);
}
}
template <class T>
static void listAccept(std::vector<T> const& _list, ASTConstVisitor& _visitor)
{
for (T const& element: _list)
if (element)
{
solAssert(element);
element->accept(_visitor);
}
}
/// @returns a copy of the vector containing only the nodes which derive from T.
template <class T>

View File

@ -23,7 +23,6 @@
#include <libsolidity/ast/ASTAnnotations.h>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;

View File

@ -44,7 +44,6 @@
#include <type_traits>
#include <range/v3/view/map.hpp>
using namespace std;
using namespace std::string_literals;
using namespace solidity::langutil;
@ -52,14 +51,14 @@ namespace
{
template<typename V, template<typename> typename C>
void addIfSet(std::vector<pair<string, Json::Value>>& _attributes, string const& _name, C<V> const& _value)
void addIfSet(std::vector<std::pair<std::string, Json::Value>>& _attributes, std::string const& _name, C<V> const& _value)
{
if constexpr (std::is_same_v<C<V>, solidity::util::SetOnce<V>>)
{
if (!_value.set())
return;
}
else if constexpr (std::is_same_v<C<V>, optional<V>>)
else if constexpr (std::is_same_v<C<V>, std::optional<V>>)
{
if (!_value.has_value())
return;
@ -73,7 +72,7 @@ void addIfSet(std::vector<pair<string, Json::Value>>& _attributes, string const&
namespace solidity::frontend
{
ASTJsonExporter::ASTJsonExporter(CompilerStack::State _stackState, map<string, unsigned> _sourceIndices):
ASTJsonExporter::ASTJsonExporter(CompilerStack::State _stackState, std::map<std::string, unsigned> _sourceIndices):
m_stackState(_stackState),
m_sourceIndices(std::move(_sourceIndices))
{
@ -82,21 +81,21 @@ ASTJsonExporter::ASTJsonExporter(CompilerStack::State _stackState, map<string, u
void ASTJsonExporter::setJsonNode(
ASTNode const& _node,
string const& _nodeName,
initializer_list<pair<string, Json::Value>>&& _attributes
std::string const& _nodeName,
std::initializer_list<std::pair<std::string, Json::Value>>&& _attributes
)
{
ASTJsonExporter::setJsonNode(
_node,
_nodeName,
std::vector<pair<string, Json::Value>>(std::move(_attributes))
std::vector<std::pair<std::string, Json::Value>>(std::move(_attributes))
);
}
void ASTJsonExporter::setJsonNode(
ASTNode const& _node,
string const& _nodeType,
std::vector<pair<string, Json::Value>>&& _attributes
std::string const& _nodeType,
std::vector<std::pair<std::string, Json::Value>>&& _attributes
)
{
m_currentValue = Json::objectValue;
@ -110,24 +109,24 @@ void ASTJsonExporter::setJsonNode(
m_currentValue[e.first] = std::move(e.second);
}
optional<size_t> ASTJsonExporter::sourceIndexFromLocation(SourceLocation const& _location) const
std::optional<size_t> ASTJsonExporter::sourceIndexFromLocation(SourceLocation const& _location) const
{
if (_location.sourceName && m_sourceIndices.count(*_location.sourceName))
return m_sourceIndices.at(*_location.sourceName);
else
return nullopt;
return std::nullopt;
}
string ASTJsonExporter::sourceLocationToString(SourceLocation const& _location) const
std::string ASTJsonExporter::sourceLocationToString(SourceLocation const& _location) const
{
optional<size_t> sourceIndexOpt = sourceIndexFromLocation(_location);
std::optional<size_t> sourceIndexOpt = sourceIndexFromLocation(_location);
int length = -1;
if (_location.start >= 0 && _location.end >= 0)
length = _location.end - _location.start;
return to_string(_location.start) + ":" + to_string(length) + ":" + (sourceIndexOpt.has_value() ? to_string(sourceIndexOpt.value()) : "-1");
return std::to_string(_location.start) + ":" + std::to_string(length) + ":" + (sourceIndexOpt.has_value() ? std::to_string(sourceIndexOpt.value()) : "-1");
}
Json::Value ASTJsonExporter::sourceLocationsToJson(vector<SourceLocation> const& _sourceLocations) const
Json::Value ASTJsonExporter::sourceLocationsToJson(std::vector<SourceLocation> const& _sourceLocations) const
{
Json::Value locations = Json::arrayValue;
@ -137,7 +136,7 @@ Json::Value ASTJsonExporter::sourceLocationsToJson(vector<SourceLocation> const&
return locations;
}
string ASTJsonExporter::namePathToString(std::vector<ASTString> const& _namePath)
std::string ASTJsonExporter::namePathToString(std::vector<ASTString> const& _namePath)
{
return boost::algorithm::join(_namePath, "."s);
}
@ -164,13 +163,13 @@ Json::Value ASTJsonExporter::typePointerToJson(std::optional<FuncCallArguments>
}
void ASTJsonExporter::appendExpressionAttributes(
std::vector<pair<string, Json::Value>>& _attributes,
std::vector<std::pair<std::string, Json::Value>>& _attributes,
ExpressionAnnotation const& _annotation
)
{
std::vector<pair<string, Json::Value>> exprAttributes = {
make_pair("typeDescriptions", typePointerToJson(_annotation.type)),
make_pair("argumentTypes", typePointerToJson(_annotation.arguments))
std::vector<std::pair<std::string, Json::Value>> exprAttributes = {
std::make_pair("typeDescriptions", typePointerToJson(_annotation.type)),
std::make_pair("argumentTypes", typePointerToJson(_annotation.arguments))
};
addIfSet(exprAttributes, "isLValue", _annotation.isLValue);
@ -183,7 +182,7 @@ void ASTJsonExporter::appendExpressionAttributes(
_attributes += exprAttributes;
}
Json::Value ASTJsonExporter::inlineAssemblyIdentifierToJson(pair<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const
Json::Value ASTJsonExporter::inlineAssemblyIdentifierToJson(std::pair<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const
{
Json::Value tuple(Json::objectValue);
tuple["src"] = sourceLocationToString(nativeLocationOf(*_info.first));
@ -199,7 +198,7 @@ Json::Value ASTJsonExporter::inlineAssemblyIdentifierToJson(pair<yul::Identifier
return tuple;
}
void ASTJsonExporter::print(ostream& _stream, ASTNode const& _node, util::JsonFormat const& _format)
void ASTJsonExporter::print(std::ostream& _stream, ASTNode const& _node, util::JsonFormat const& _format)
{
_stream << util::jsonPrint(toJson(_node), _format);
}
@ -212,9 +211,9 @@ Json::Value ASTJsonExporter::toJson(ASTNode const& _node)
bool ASTJsonExporter::visit(SourceUnit const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("license", _node.licenseString() ? Json::Value(*_node.licenseString()) : Json::nullValue),
make_pair("nodes", toJson(_node.nodes())),
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("license", _node.licenseString() ? Json::Value(*_node.licenseString()) : Json::nullValue),
std::make_pair("nodes", toJson(_node.nodes())),
};
if (_node.experimentalSolidity())
@ -246,17 +245,17 @@ bool ASTJsonExporter::visit(PragmaDirective const& _node)
for (auto const& literal: _node.literals())
literals.append(literal);
setJsonNode(_node, "PragmaDirective", {
make_pair("literals", std::move(literals))
std::make_pair("literals", std::move(literals))
});
return false;
}
bool ASTJsonExporter::visit(ImportDirective const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("file", _node.path()),
make_pair("sourceUnit", idOrNull(_node.annotation().sourceUnit)),
make_pair("scope", idOrNull(_node.scope()))
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("file", _node.path()),
std::make_pair("sourceUnit", idOrNull(_node.annotation().sourceUnit)),
std::make_pair("scope", idOrNull(_node.scope()))
};
addIfSet(attributes, "absolutePath", _node.annotation().absolutePath);
@ -281,19 +280,19 @@ bool ASTJsonExporter::visit(ImportDirective const& _node)
bool ASTJsonExporter::visit(ContractDefinition const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("name", _node.name()),
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
make_pair("contractKind", contractKind(_node.contractKind())),
make_pair("abstract", _node.abstract()),
make_pair("baseContracts", toJson(_node.baseContracts())),
make_pair("contractDependencies", getContainerIds(_node.annotation().contractDependencies | ranges::views::keys)),
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("name", _node.name()),
std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
std::make_pair("contractKind", contractKind(_node.contractKind())),
std::make_pair("abstract", _node.abstract()),
std::make_pair("baseContracts", toJson(_node.baseContracts())),
std::make_pair("contractDependencies", getContainerIds(_node.annotation().contractDependencies | ranges::views::keys)),
// Do not require call graph because the AST is also created for incorrect sources.
make_pair("usedEvents", getContainerIds(_node.interfaceEvents(false))),
make_pair("usedErrors", getContainerIds(_node.interfaceErrors(false))),
make_pair("nodes", toJson(_node.subNodes())),
make_pair("scope", idOrNull(_node.scope()))
std::make_pair("usedEvents", getContainerIds(_node.interfaceEvents(false))),
std::make_pair("usedErrors", getContainerIds(_node.interfaceErrors(false))),
std::make_pair("nodes", toJson(_node.subNodes())),
std::make_pair("scope", idOrNull(_node.scope()))
};
addIfSet(attributes, "canonicalName", _node.annotation().canonicalName);
@ -306,7 +305,7 @@ bool ASTJsonExporter::visit(ContractDefinition const& _node)
{
Json::Value internalFunctionIDs(Json::objectValue);
for (auto const& [functionDefinition, internalFunctionID]: _node.annotation().internalFunctionIDs)
internalFunctionIDs[to_string(functionDefinition->id())] = internalFunctionID;
internalFunctionIDs[std::to_string(functionDefinition->id())] = internalFunctionID;
attributes.emplace_back("internalFunctionIDs", std::move(internalFunctionIDs));
}
@ -322,9 +321,9 @@ bool ASTJsonExporter::visit(IdentifierPath const& _node)
nameLocations.append(sourceLocationToString(location));
setJsonNode(_node, "IdentifierPath", {
make_pair("name", namePathToString(_node.path())),
make_pair("nameLocations", nameLocations),
make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration))
std::make_pair("name", namePathToString(_node.path())),
std::make_pair("nameLocations", nameLocations),
std::make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration))
});
return false;
}
@ -332,16 +331,16 @@ bool ASTJsonExporter::visit(IdentifierPath const& _node)
bool ASTJsonExporter::visit(InheritanceSpecifier const& _node)
{
setJsonNode(_node, "InheritanceSpecifier", {
make_pair("baseName", toJson(_node.name())),
make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json::nullValue)
std::make_pair("baseName", toJson(_node.name())),
std::make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json::nullValue)
});
return false;
}
bool ASTJsonExporter::visit(UsingForDirective const& _node)
{
vector<pair<string, Json::Value>> attributes = {
make_pair("typeName", _node.typeName() ? toJson(*_node.typeName()) : Json::nullValue)
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("typeName", _node.typeName() ? toJson(*_node.typeName()) : Json::nullValue)
};
if (_node.usesBraces())
@ -355,7 +354,7 @@ bool ASTJsonExporter::visit(UsingForDirective const& _node)
else
{
functionNode["definition"] = toJson(*function);
functionNode["operator"] = string(TokenTraits::toString(*op));
functionNode["operator"] = std::string(TokenTraits::toString(*op));
}
functionList.append(std::move(functionNode));
}
@ -377,13 +376,13 @@ bool ASTJsonExporter::visit(UsingForDirective const& _node)
bool ASTJsonExporter::visit(StructDefinition const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("name", _node.name()),
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
make_pair("members", toJson(_node.members())),
make_pair("scope", idOrNull(_node.scope()))
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("name", _node.name()),
std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
std::make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
std::make_pair("members", toJson(_node.members())),
std::make_pair("scope", idOrNull(_node.scope()))
};
addIfSet(attributes,"canonicalName", _node.annotation().canonicalName);
@ -395,11 +394,11 @@ bool ASTJsonExporter::visit(StructDefinition const& _node)
bool ASTJsonExporter::visit(EnumDefinition const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("name", _node.name()),
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
make_pair("members", toJson(_node.members()))
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("name", _node.name()),
std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
std::make_pair("members", toJson(_node.members()))
};
addIfSet(attributes,"canonicalName", _node.annotation().canonicalName);
@ -412,8 +411,8 @@ bool ASTJsonExporter::visit(EnumDefinition const& _node)
bool ASTJsonExporter::visit(EnumValue const& _node)
{
setJsonNode(_node, "EnumValue", {
make_pair("name", _node.name()),
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
std::make_pair("name", _node.name()),
std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
});
return false;
}
@ -421,10 +420,10 @@ bool ASTJsonExporter::visit(EnumValue const& _node)
bool ASTJsonExporter::visit(UserDefinedValueTypeDefinition const& _node)
{
solAssert(_node.underlyingType(), "");
std::vector<pair<string, Json::Value>> attributes = {
make_pair("name", _node.name()),
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
make_pair("underlyingType", toJson(*_node.underlyingType()))
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("name", _node.name()),
std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
std::make_pair("underlyingType", toJson(*_node.underlyingType()))
};
addIfSet(attributes, "canonicalName", _node.annotation().canonicalName);
@ -436,7 +435,7 @@ bool ASTJsonExporter::visit(UserDefinedValueTypeDefinition const& _node)
bool ASTJsonExporter::visit(ParameterList const& _node)
{
setJsonNode(_node, "ParameterList", {
make_pair("parameters", toJson(_node.parameters()))
std::make_pair("parameters", toJson(_node.parameters()))
});
return false;
}
@ -444,30 +443,30 @@ bool ASTJsonExporter::visit(ParameterList const& _node)
bool ASTJsonExporter::visit(OverrideSpecifier const& _node)
{
setJsonNode(_node, "OverrideSpecifier", {
make_pair("overrides", toJson(_node.overrides()))
std::make_pair("overrides", toJson(_node.overrides()))
});
return false;
}
bool ASTJsonExporter::visit(FunctionDefinition const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("name", _node.name()),
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
make_pair("kind", _node.isFree() ? "freeFunction" : TokenTraits::toString(_node.kind())),
make_pair("stateMutability", stateMutabilityToString(_node.stateMutability())),
make_pair("virtual", _node.markedVirtual()),
make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue),
make_pair("parameters", toJson(_node.parameterList())),
make_pair("returnParameters", toJson(*_node.returnParameterList())),
make_pair("modifiers", toJson(_node.modifiers())),
make_pair("body", _node.isImplemented() ? toJson(_node.body()) : Json::nullValue),
make_pair("implemented", _node.isImplemented()),
make_pair("scope", idOrNull(_node.scope()))
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("name", _node.name()),
std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
std::make_pair("kind", _node.isFree() ? "freeFunction" : TokenTraits::toString(_node.kind())),
std::make_pair("stateMutability", stateMutabilityToString(_node.stateMutability())),
std::make_pair("virtual", _node.markedVirtual()),
std::make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue),
std::make_pair("parameters", toJson(_node.parameterList())),
std::make_pair("returnParameters", toJson(*_node.returnParameterList())),
std::make_pair("modifiers", toJson(_node.modifiers())),
std::make_pair("body", _node.isImplemented() ? toJson(_node.body()) : Json::nullValue),
std::make_pair("implemented", _node.isImplemented()),
std::make_pair("scope", idOrNull(_node.scope()))
};
optional<Visibility> visibility;
std::optional<Visibility> visibility;
if (_node.isConstructor())
{
if (_node.annotation().contract)
@ -482,7 +481,7 @@ bool ASTJsonExporter::visit(FunctionDefinition const& _node)
if (_node.isPartOfExternalInterface() && m_stackState > CompilerStack::State::ParsedAndImported)
attributes.emplace_back("functionSelector", _node.externalIdentifierHex());
if (!_node.annotation().baseFunctions.empty())
attributes.emplace_back(make_pair("baseFunctions", getContainerIds(_node.annotation().baseFunctions, true)));
attributes.emplace_back(std::make_pair("baseFunctions", getContainerIds(_node.annotation().baseFunctions, true)));
setJsonNode(_node, "FunctionDefinition", std::move(attributes));
return false;
@ -490,19 +489,19 @@ bool ASTJsonExporter::visit(FunctionDefinition const& _node)
bool ASTJsonExporter::visit(VariableDeclaration const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("name", _node.name()),
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
make_pair("typeName", toJson(_node.typeName())),
make_pair("constant", _node.isConstant()),
make_pair("mutability", VariableDeclaration::mutabilityToString(_node.mutability())),
make_pair("stateVariable", _node.isStateVariable()),
make_pair("storageLocation", location(_node.referenceLocation())),
make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue),
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
make_pair("value", _node.value() ? toJson(*_node.value()) : Json::nullValue),
make_pair("scope", idOrNull(_node.scope())),
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("name", _node.name()),
std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
std::make_pair("typeName", toJson(_node.typeName())),
std::make_pair("constant", _node.isConstant()),
std::make_pair("mutability", VariableDeclaration::mutabilityToString(_node.mutability())),
std::make_pair("stateVariable", _node.isStateVariable()),
std::make_pair("storageLocation", location(_node.referenceLocation())),
std::make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue),
std::make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
std::make_pair("value", _node.value() ? toJson(*_node.value()) : Json::nullValue),
std::make_pair("scope", idOrNull(_node.scope())),
std::make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
};
if (_node.isStateVariable() && _node.isPublic())
attributes.emplace_back("functionSelector", _node.externalIdentifierHex());
@ -511,34 +510,34 @@ bool ASTJsonExporter::visit(VariableDeclaration const& _node)
if (m_inEvent)
attributes.emplace_back("indexed", _node.isIndexed());
if (!_node.annotation().baseFunctions.empty())
attributes.emplace_back(make_pair("baseFunctions", getContainerIds(_node.annotation().baseFunctions, true)));
attributes.emplace_back(std::make_pair("baseFunctions", getContainerIds(_node.annotation().baseFunctions, true)));
setJsonNode(_node, "VariableDeclaration", std::move(attributes));
return false;
}
bool ASTJsonExporter::visit(ModifierDefinition const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("name", _node.name()),
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
make_pair("parameters", toJson(_node.parameterList())),
make_pair("virtual", _node.markedVirtual()),
make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue),
make_pair("body", _node.isImplemented() ? toJson(_node.body()) : Json::nullValue)
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("name", _node.name()),
std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
std::make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
std::make_pair("parameters", toJson(_node.parameterList())),
std::make_pair("virtual", _node.markedVirtual()),
std::make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue),
std::make_pair("body", _node.isImplemented() ? toJson(_node.body()) : Json::nullValue)
};
if (!_node.annotation().baseFunctions.empty())
attributes.emplace_back(make_pair("baseModifiers", getContainerIds(_node.annotation().baseFunctions, true)));
attributes.emplace_back(std::make_pair("baseModifiers", getContainerIds(_node.annotation().baseFunctions, true)));
setJsonNode(_node, "ModifierDefinition", std::move(attributes));
return false;
}
bool ASTJsonExporter::visit(ModifierInvocation const& _node)
{
std::vector<pair<string, Json::Value>> attributes{
make_pair("modifierName", toJson(_node.name())),
make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json::nullValue)
std::vector<std::pair<std::string, Json::Value>> attributes{
std::make_pair("modifierName", toJson(_node.name())),
std::make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json::nullValue)
};
if (Declaration const* declaration = _node.name().annotation().referencedDeclaration)
{
@ -554,16 +553,16 @@ bool ASTJsonExporter::visit(ModifierInvocation const& _node)
bool ASTJsonExporter::visit(EventDefinition const& _node)
{
m_inEvent = true;
std::vector<pair<string, Json::Value>> _attributes = {
make_pair("name", _node.name()),
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
make_pair("parameters", toJson(_node.parameterList())),
make_pair("anonymous", _node.isAnonymous())
std::vector<std::pair<std::string, Json::Value>> _attributes = {
std::make_pair("name", _node.name()),
std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
std::make_pair("parameters", toJson(_node.parameterList())),
std::make_pair("anonymous", _node.isAnonymous())
};
if (m_stackState >= CompilerStack::State::AnalysisPerformed)
if (m_stackState >= CompilerStack::State::AnalysisSuccessful)
_attributes.emplace_back(
make_pair(
std::make_pair(
"eventSelector",
toHex(u256(util::h256::Arith(util::keccak256(_node.functionType(true)->externalSignature()))))
));
@ -574,14 +573,14 @@ bool ASTJsonExporter::visit(EventDefinition const& _node)
bool ASTJsonExporter::visit(ErrorDefinition const& _node)
{
std::vector<pair<string, Json::Value>> _attributes = {
make_pair("name", _node.name()),
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
make_pair("parameters", toJson(_node.parameterList()))
std::vector<std::pair<std::string, Json::Value>> _attributes = {
std::make_pair("name", _node.name()),
std::make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
std::make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
std::make_pair("parameters", toJson(_node.parameterList()))
};
if (m_stackState >= CompilerStack::State::AnalysisPerformed)
_attributes.emplace_back(make_pair("errorSelector", _node.functionType(true)->externalIdentifierHex()));
if (m_stackState >= CompilerStack::State::AnalysisSuccessful)
_attributes.emplace_back(std::make_pair("errorSelector", _node.functionType(true)->externalIdentifierHex()));
setJsonNode(_node, "ErrorDefinition", std::move(_attributes));
return false;
@ -589,13 +588,13 @@ bool ASTJsonExporter::visit(ErrorDefinition const& _node)
bool ASTJsonExporter::visit(ElementaryTypeName const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("name", _node.typeName().toString()),
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("name", _node.typeName().toString()),
std::make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
};
if (_node.stateMutability())
attributes.emplace_back(make_pair("stateMutability", stateMutabilityToString(*_node.stateMutability())));
attributes.emplace_back(std::make_pair("stateMutability", stateMutabilityToString(*_node.stateMutability())));
setJsonNode(_node, "ElementaryTypeName", std::move(attributes));
return false;
@ -604,9 +603,9 @@ bool ASTJsonExporter::visit(ElementaryTypeName const& _node)
bool ASTJsonExporter::visit(UserDefinedTypeName const& _node)
{
setJsonNode(_node, "UserDefinedTypeName", {
make_pair("pathNode", toJson(_node.pathNode())),
make_pair("referencedDeclaration", idOrNull(_node.pathNode().annotation().referencedDeclaration)),
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
std::make_pair("pathNode", toJson(_node.pathNode())),
std::make_pair("referencedDeclaration", idOrNull(_node.pathNode().annotation().referencedDeclaration)),
std::make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
});
return false;
}
@ -614,11 +613,11 @@ bool ASTJsonExporter::visit(UserDefinedTypeName const& _node)
bool ASTJsonExporter::visit(FunctionTypeName const& _node)
{
setJsonNode(_node, "FunctionTypeName", {
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
make_pair("stateMutability", stateMutabilityToString(_node.stateMutability())),
make_pair("parameterTypes", toJson(*_node.parameterTypeList())),
make_pair("returnParameterTypes", toJson(*_node.returnParameterTypeList())),
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
std::make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
std::make_pair("stateMutability", stateMutabilityToString(_node.stateMutability())),
std::make_pair("parameterTypes", toJson(*_node.parameterTypeList())),
std::make_pair("returnParameterTypes", toJson(*_node.returnParameterTypeList())),
std::make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
});
return false;
}
@ -626,13 +625,13 @@ bool ASTJsonExporter::visit(FunctionTypeName const& _node)
bool ASTJsonExporter::visit(Mapping const& _node)
{
setJsonNode(_node, "Mapping", {
make_pair("keyType", toJson(_node.keyType())),
make_pair("keyName", _node.keyName()),
make_pair("keyNameLocation", sourceLocationToString(_node.keyNameLocation())),
make_pair("valueType", toJson(_node.valueType())),
make_pair("valueName", _node.valueName()),
make_pair("valueNameLocation", sourceLocationToString(_node.valueNameLocation())),
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
std::make_pair("keyType", toJson(_node.keyType())),
std::make_pair("keyName", _node.keyName()),
std::make_pair("keyNameLocation", sourceLocationToString(_node.keyNameLocation())),
std::make_pair("valueType", toJson(_node.valueType())),
std::make_pair("valueName", _node.valueName()),
std::make_pair("valueNameLocation", sourceLocationToString(_node.valueNameLocation())),
std::make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
});
return false;
}
@ -640,20 +639,20 @@ bool ASTJsonExporter::visit(Mapping const& _node)
bool ASTJsonExporter::visit(ArrayTypeName const& _node)
{
setJsonNode(_node, "ArrayTypeName", {
make_pair("baseType", toJson(_node.baseType())),
make_pair("length", toJsonOrNull(_node.length())),
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
std::make_pair("baseType", toJson(_node.baseType())),
std::make_pair("length", toJsonOrNull(_node.length())),
std::make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
});
return false;
}
bool ASTJsonExporter::visit(InlineAssembly const& _node)
{
vector<pair<string, Json::Value>> externalReferences;
std::vector<std::pair<std::string, Json::Value>> externalReferences;
for (auto const& it: _node.annotation().externalReferences)
if (it.first)
externalReferences.emplace_back(make_pair(
externalReferences.emplace_back(std::make_pair(
it.first->name.str(),
inlineAssemblyIdentifierToJson(it)
));
@ -664,10 +663,10 @@ bool ASTJsonExporter::visit(InlineAssembly const& _node)
for (Json::Value& it: externalReferences | ranges::views::values)
externalReferencesJson.append(std::move(it));
std::vector<pair<string, Json::Value>> attributes = {
make_pair("AST", Json::Value(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations()))),
make_pair("externalReferences", std::move(externalReferencesJson)),
make_pair("evmVersion", dynamic_cast<solidity::yul::EVMDialect const&>(_node.dialect()).evmVersion().name())
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("AST", Json::Value(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations()))),
std::make_pair("externalReferences", std::move(externalReferencesJson)),
std::make_pair("evmVersion", dynamic_cast<solidity::yul::EVMDialect const&>(_node.dialect()).evmVersion().name())
};
if (_node.flags())
@ -678,7 +677,7 @@ bool ASTJsonExporter::visit(InlineAssembly const& _node)
flags.append(*flag);
else
flags.append(Json::nullValue);
attributes.emplace_back(make_pair("flags", std::move(flags)));
attributes.emplace_back(std::make_pair("flags", std::move(flags)));
}
setJsonNode(_node, "InlineAssembly", std::move(attributes));
@ -688,7 +687,7 @@ bool ASTJsonExporter::visit(InlineAssembly const& _node)
bool ASTJsonExporter::visit(Block const& _node)
{
setJsonNode(_node, _node.unchecked() ? "UncheckedBlock" : "Block", {
make_pair("statements", toJson(_node.statements()))
std::make_pair("statements", toJson(_node.statements()))
});
return false;
}
@ -702,9 +701,9 @@ bool ASTJsonExporter::visit(PlaceholderStatement const& _node)
bool ASTJsonExporter::visit(IfStatement const& _node)
{
setJsonNode(_node, "IfStatement", {
make_pair("condition", toJson(_node.condition())),
make_pair("trueBody", toJson(_node.trueStatement())),
make_pair("falseBody", toJsonOrNull(_node.falseStatement()))
std::make_pair("condition", toJson(_node.condition())),
std::make_pair("trueBody", toJson(_node.trueStatement())),
std::make_pair("falseBody", toJsonOrNull(_node.falseStatement()))
});
return false;
}
@ -712,9 +711,9 @@ bool ASTJsonExporter::visit(IfStatement const& _node)
bool ASTJsonExporter::visit(TryCatchClause const& _node)
{
setJsonNode(_node, "TryCatchClause", {
make_pair("errorName", _node.errorName()),
make_pair("parameters", toJsonOrNull(_node.parameters())),
make_pair("block", toJson(_node.block()))
std::make_pair("errorName", _node.errorName()),
std::make_pair("parameters", toJsonOrNull(_node.parameters())),
std::make_pair("block", toJson(_node.block()))
});
return false;
}
@ -722,8 +721,8 @@ bool ASTJsonExporter::visit(TryCatchClause const& _node)
bool ASTJsonExporter::visit(TryStatement const& _node)
{
setJsonNode(_node, "TryStatement", {
make_pair("externalCall", toJson(_node.externalCall())),
make_pair("clauses", toJson(_node.clauses()))
std::make_pair("externalCall", toJson(_node.externalCall())),
std::make_pair("clauses", toJson(_node.clauses()))
});
return false;
}
@ -734,8 +733,8 @@ bool ASTJsonExporter::visit(WhileStatement const& _node)
_node,
_node.isDoWhile() ? "DoWhileStatement" : "WhileStatement",
{
make_pair("condition", toJson(_node.condition())),
make_pair("body", toJson(_node.body()))
std::make_pair("condition", toJson(_node.condition())),
std::make_pair("body", toJson(_node.body()))
}
);
return false;
@ -744,10 +743,10 @@ bool ASTJsonExporter::visit(WhileStatement const& _node)
bool ASTJsonExporter::visit(ForStatement const& _node)
{
setJsonNode(_node, "ForStatement", {
make_pair("initializationExpression", toJsonOrNull(_node.initializationExpression())),
make_pair("condition", toJsonOrNull(_node.condition())),
make_pair("loopExpression", toJsonOrNull(_node.loopExpression())),
make_pair("body", toJson(_node.body()))
std::make_pair("initializationExpression", toJsonOrNull(_node.initializationExpression())),
std::make_pair("condition", toJsonOrNull(_node.condition())),
std::make_pair("loopExpression", toJsonOrNull(_node.loopExpression())),
std::make_pair("body", toJson(_node.body()))
});
return false;
}
@ -767,8 +766,8 @@ bool ASTJsonExporter::visit(Break const& _node)
bool ASTJsonExporter::visit(Return const& _node)
{
setJsonNode(_node, "Return", {
make_pair("expression", toJsonOrNull(_node.expression())),
make_pair("functionReturnParameters", idOrNull(_node.annotation().functionReturnParameters))
std::make_pair("expression", toJsonOrNull(_node.expression())),
std::make_pair("functionReturnParameters", idOrNull(_node.annotation().functionReturnParameters))
});
return false;
}
@ -782,7 +781,7 @@ bool ASTJsonExporter::visit(Throw const& _node)
bool ASTJsonExporter::visit(EmitStatement const& _node)
{
setJsonNode(_node, "EmitStatement", {
make_pair("eventCall", toJson(_node.eventCall()))
std::make_pair("eventCall", toJson(_node.eventCall()))
});
return false;
}
@ -790,7 +789,7 @@ bool ASTJsonExporter::visit(EmitStatement const& _node)
bool ASTJsonExporter::visit(RevertStatement const& _node)
{
setJsonNode(_node, "RevertStatement", {
make_pair("errorCall", toJson(_node.errorCall()))
std::make_pair("errorCall", toJson(_node.errorCall()))
});
return false;
}
@ -801,9 +800,9 @@ bool ASTJsonExporter::visit(VariableDeclarationStatement const& _node)
for (auto const& v: _node.declarations())
appendMove(varDecs, idOrNull(v.get()));
setJsonNode(_node, "VariableDeclarationStatement", {
make_pair("assignments", std::move(varDecs)),
make_pair("declarations", toJson(_node.declarations())),
make_pair("initialValue", toJsonOrNull(_node.initialValue()))
std::make_pair("assignments", std::move(varDecs)),
std::make_pair("declarations", toJson(_node.declarations())),
std::make_pair("initialValue", toJsonOrNull(_node.initialValue()))
});
return false;
}
@ -811,17 +810,17 @@ bool ASTJsonExporter::visit(VariableDeclarationStatement const& _node)
bool ASTJsonExporter::visit(ExpressionStatement const& _node)
{
setJsonNode(_node, "ExpressionStatement", {
make_pair("expression", toJson(_node.expression()))
std::make_pair("expression", toJson(_node.expression()))
});
return false;
}
bool ASTJsonExporter::visit(Conditional const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("condition", toJson(_node.condition())),
make_pair("trueExpression", toJson(_node.trueExpression())),
make_pair("falseExpression", toJson(_node.falseExpression()))
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("condition", toJson(_node.condition())),
std::make_pair("trueExpression", toJson(_node.trueExpression())),
std::make_pair("falseExpression", toJson(_node.falseExpression()))
};
appendExpressionAttributes(attributes, _node.annotation());
setJsonNode(_node, "Conditional", std::move(attributes));
@ -830,10 +829,10 @@ bool ASTJsonExporter::visit(Conditional const& _node)
bool ASTJsonExporter::visit(Assignment const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("operator", TokenTraits::toString(_node.assignmentOperator())),
make_pair("leftHandSide", toJson(_node.leftHandSide())),
make_pair("rightHandSide", toJson(_node.rightHandSide()))
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("operator", TokenTraits::toString(_node.assignmentOperator())),
std::make_pair("leftHandSide", toJson(_node.leftHandSide())),
std::make_pair("rightHandSide", toJson(_node.rightHandSide()))
};
appendExpressionAttributes(attributes, _node.annotation());
setJsonNode(_node, "Assignment", std::move(attributes));
@ -842,9 +841,9 @@ bool ASTJsonExporter::visit(Assignment const& _node)
bool ASTJsonExporter::visit(TupleExpression const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("isInlineArray", Json::Value(_node.isInlineArray())),
make_pair("components", toJson(_node.components())),
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("isInlineArray", Json::Value(_node.isInlineArray())),
std::make_pair("components", toJson(_node.components())),
};
appendExpressionAttributes(attributes, _node.annotation());
setJsonNode(_node, "TupleExpression", std::move(attributes));
@ -853,10 +852,10 @@ bool ASTJsonExporter::visit(TupleExpression const& _node)
bool ASTJsonExporter::visit(UnaryOperation const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("prefix", _node.isPrefixOperation()),
make_pair("operator", TokenTraits::toString(_node.getOperator())),
make_pair("subExpression", toJson(_node.subExpression()))
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("prefix", _node.isPrefixOperation()),
std::make_pair("operator", TokenTraits::toString(_node.getOperator())),
std::make_pair("subExpression", toJson(_node.subExpression()))
};
// NOTE: This annotation is guaranteed to be set but only if we didn't stop at the parsing stage.
if (_node.annotation().userDefinedFunction.set() && *_node.annotation().userDefinedFunction != nullptr)
@ -868,11 +867,11 @@ bool ASTJsonExporter::visit(UnaryOperation const& _node)
bool ASTJsonExporter::visit(BinaryOperation const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("operator", TokenTraits::toString(_node.getOperator())),
make_pair("leftExpression", toJson(_node.leftExpression())),
make_pair("rightExpression", toJson(_node.rightExpression())),
make_pair("commonType", typePointerToJson(_node.annotation().commonType)),
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("operator", TokenTraits::toString(_node.getOperator())),
std::make_pair("leftExpression", toJson(_node.leftExpression())),
std::make_pair("rightExpression", toJson(_node.rightExpression())),
std::make_pair("commonType", typePointerToJson(_node.annotation().commonType)),
};
// NOTE: This annotation is guaranteed to be set but only if we didn't stop at the parsing stage.
if (_node.annotation().userDefinedFunction.set() && *_node.annotation().userDefinedFunction != nullptr)
@ -887,12 +886,12 @@ bool ASTJsonExporter::visit(FunctionCall const& _node)
Json::Value names(Json::arrayValue);
for (auto const& name: _node.names())
names.append(Json::Value(*name));
std::vector<pair<string, Json::Value>> attributes = {
make_pair("expression", toJson(_node.expression())),
make_pair("names", std::move(names)),
make_pair("nameLocations", sourceLocationsToJson(_node.nameLocations())),
make_pair("arguments", toJson(_node.arguments())),
make_pair("tryCall", _node.annotation().tryCall)
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("expression", toJson(_node.expression())),
std::make_pair("names", std::move(names)),
std::make_pair("nameLocations", sourceLocationsToJson(_node.nameLocations())),
std::make_pair("arguments", toJson(_node.arguments())),
std::make_pair("tryCall", _node.annotation().tryCall)
};
if (_node.annotation().kind.set())
@ -912,10 +911,10 @@ bool ASTJsonExporter::visit(FunctionCallOptions const& _node)
for (auto const& name: _node.names())
names.append(Json::Value(*name));
std::vector<pair<string, Json::Value>> attributes = {
make_pair("expression", toJson(_node.expression())),
make_pair("names", std::move(names)),
make_pair("options", toJson(_node.options())),
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("expression", toJson(_node.expression())),
std::make_pair("names", std::move(names)),
std::make_pair("options", toJson(_node.options())),
};
appendExpressionAttributes(attributes, _node.annotation());
@ -925,8 +924,8 @@ bool ASTJsonExporter::visit(FunctionCallOptions const& _node)
bool ASTJsonExporter::visit(NewExpression const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("typeName", toJson(_node.typeName()))
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("typeName", toJson(_node.typeName()))
};
appendExpressionAttributes(attributes, _node.annotation());
setJsonNode(_node, "NewExpression", std::move(attributes));
@ -935,11 +934,11 @@ bool ASTJsonExporter::visit(NewExpression const& _node)
bool ASTJsonExporter::visit(MemberAccess const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("memberName", _node.memberName()),
make_pair("memberLocation", Json::Value(sourceLocationToString(_node.memberLocation()))),
make_pair("expression", toJson(_node.expression())),
make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)),
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("memberName", _node.memberName()),
std::make_pair("memberLocation", Json::Value(sourceLocationToString(_node.memberLocation()))),
std::make_pair("expression", toJson(_node.expression())),
std::make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)),
};
appendExpressionAttributes(attributes, _node.annotation());
setJsonNode(_node, "MemberAccess", std::move(attributes));
@ -948,9 +947,9 @@ bool ASTJsonExporter::visit(MemberAccess const& _node)
bool ASTJsonExporter::visit(IndexAccess const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("baseExpression", toJson(_node.baseExpression())),
make_pair("indexExpression", toJsonOrNull(_node.indexExpression())),
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("baseExpression", toJson(_node.baseExpression())),
std::make_pair("indexExpression", toJsonOrNull(_node.indexExpression())),
};
appendExpressionAttributes(attributes, _node.annotation());
setJsonNode(_node, "IndexAccess", std::move(attributes));
@ -959,10 +958,10 @@ bool ASTJsonExporter::visit(IndexAccess const& _node)
bool ASTJsonExporter::visit(IndexRangeAccess const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("baseExpression", toJson(_node.baseExpression())),
make_pair("startExpression", toJsonOrNull(_node.startExpression())),
make_pair("endExpression", toJsonOrNull(_node.endExpression())),
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("baseExpression", toJson(_node.baseExpression())),
std::make_pair("startExpression", toJsonOrNull(_node.startExpression())),
std::make_pair("endExpression", toJsonOrNull(_node.endExpression())),
};
appendExpressionAttributes(attributes, _node.annotation());
setJsonNode(_node, "IndexRangeAccess", std::move(attributes));
@ -975,19 +974,19 @@ bool ASTJsonExporter::visit(Identifier const& _node)
for (auto const& dec: _node.annotation().overloadedDeclarations)
overloads.append(nodeId(*dec));
setJsonNode(_node, "Identifier", {
make_pair("name", _node.name()),
make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)),
make_pair("overloadedDeclarations", overloads),
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type)),
make_pair("argumentTypes", typePointerToJson(_node.annotation().arguments))
std::make_pair("name", _node.name()),
std::make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)),
std::make_pair("overloadedDeclarations", overloads),
std::make_pair("typeDescriptions", typePointerToJson(_node.annotation().type)),
std::make_pair("argumentTypes", typePointerToJson(_node.annotation().arguments))
});
return false;
}
bool ASTJsonExporter::visit(ElementaryTypeNameExpression const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("typeName", toJson(_node.type()))
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("typeName", toJson(_node.type()))
};
appendExpressionAttributes(attributes, _node.annotation());
setJsonNode(_node, "ElementaryTypeNameExpression", std::move(attributes));
@ -1000,11 +999,11 @@ bool ASTJsonExporter::visit(Literal const& _node)
if (!util::validateUTF8(_node.value()))
value = Json::nullValue;
Token subdenomination = Token(_node.subDenomination());
std::vector<pair<string, Json::Value>> attributes = {
make_pair("kind", literalTokenKind(_node.token())),
make_pair("value", value),
make_pair("hexValue", util::toHex(util::asBytes(_node.value()))),
make_pair(
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("kind", literalTokenKind(_node.token())),
std::make_pair("value", value),
std::make_pair("hexValue", util::toHex(util::asBytes(_node.value()))),
std::make_pair(
"subdenomination",
subdenomination == Token::Illegal ?
Json::nullValue :
@ -1019,8 +1018,8 @@ bool ASTJsonExporter::visit(Literal const& _node)
bool ASTJsonExporter::visit(StructuredDocumentation const& _node)
{
Json::Value text{*_node.text()};
std::vector<pair<string, Json::Value>> attributes = {
make_pair("text", text)
std::vector<std::pair<std::string, Json::Value>> attributes = {
std::make_pair("text", text)
};
setJsonNode(_node, "StructuredDocumentation", std::move(attributes));
return false;
@ -1033,7 +1032,7 @@ void ASTJsonExporter::endVisit(EventDefinition const&)
m_inEvent = false;
}
string ASTJsonExporter::location(VariableDeclaration::Location _location)
std::string ASTJsonExporter::location(VariableDeclaration::Location _location)
{
switch (_location)
{
@ -1050,7 +1049,7 @@ string ASTJsonExporter::location(VariableDeclaration::Location _location)
return {};
}
string ASTJsonExporter::contractKind(ContractKind _kind)
std::string ASTJsonExporter::contractKind(ContractKind _kind)
{
switch (_kind)
{
@ -1066,7 +1065,7 @@ string ASTJsonExporter::contractKind(ContractKind _kind)
return {};
}
string ASTJsonExporter::functionCallKind(FunctionCallKind _kind)
std::string ASTJsonExporter::functionCallKind(FunctionCallKind _kind)
{
switch (_kind)
{
@ -1081,7 +1080,7 @@ string ASTJsonExporter::functionCallKind(FunctionCallKind _kind)
}
}
string ASTJsonExporter::literalTokenKind(Token _token)
std::string ASTJsonExporter::literalTokenKind(Token _token)
{
switch (_token)
{
@ -1101,12 +1100,12 @@ string ASTJsonExporter::literalTokenKind(Token _token)
}
}
string ASTJsonExporter::type(Expression const& _expression)
std::string ASTJsonExporter::type(Expression const& _expression)
{
return _expression.annotation().type ? _expression.annotation().type->toString() : "Unknown";
}
string ASTJsonExporter::type(VariableDeclaration const& _varDecl)
std::string ASTJsonExporter::type(VariableDeclaration const& _varDecl)
{
return _varDecl.annotation().type ? _varDecl.annotation().type->toString() : "Unknown";
}

View File

@ -37,8 +37,6 @@
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string.hpp>
using namespace std;
namespace solidity::frontend
{
@ -50,16 +48,16 @@ ASTPointer<T> ASTJsonImporter::nullOrCast(Json::Value const& _json)
if (_json.isNull())
return nullptr;
else
return dynamic_pointer_cast<T>(convertJsonToASTNode(_json));
return std::dynamic_pointer_cast<T>(convertJsonToASTNode(_json));
}
// ============ public ===========================
map<string, ASTPointer<SourceUnit>> ASTJsonImporter::jsonToSourceUnit(map<string, Json::Value> const& _sourceList)
std::map<std::string, ASTPointer<SourceUnit>> ASTJsonImporter::jsonToSourceUnit(std::map<std::string, Json::Value> const& _sourceList)
{
for (auto const& src: _sourceList)
m_sourceNames.emplace_back(make_shared<string const>(src.first));
m_sourceNames.emplace_back(std::make_shared<std::string const>(src.first));
for (auto const& srcPair: _sourceList)
{
astAssert(!srcPair.second.isNull());
@ -81,7 +79,7 @@ ASTPointer<T> ASTJsonImporter::createASTNode(Json::Value const& _node, Args&&...
astAssert(m_usedIDs.insert(id).second, "Found duplicate node ID!");
auto n = make_shared<T>(
auto n = std::make_shared<T>(
id,
createSourceLocation(_node),
std::forward<Args>(_args)...
@ -96,9 +94,9 @@ SourceLocation const ASTJsonImporter::createSourceLocation(Json::Value const& _n
return solidity::langutil::parseSourceLocation(_node["src"].asString(), m_sourceNames);
}
optional<vector<SourceLocation>> ASTJsonImporter::createSourceLocations(Json::Value const& _node) const
std::optional<std::vector<SourceLocation>> ASTJsonImporter::createSourceLocations(Json::Value const& _node) const
{
vector<SourceLocation> locations;
std::vector<SourceLocation> locations;
if (_node.isMember("nameLocations") && _node["nameLocations"].isArray())
{
@ -107,7 +105,7 @@ optional<vector<SourceLocation>> ASTJsonImporter::createSourceLocations(Json::Va
return locations;
}
return nullopt;
return std::nullopt;
}
SourceLocation ASTJsonImporter::createNameSourceLocation(Json::Value const& _node)
@ -134,7 +132,7 @@ SourceLocation ASTJsonImporter::createValueNameSourceLocation(Json::Value const&
template<class T>
ASTPointer<T> ASTJsonImporter::convertJsonToASTNode(Json::Value const& _node)
{
ASTPointer<T> ret = dynamic_pointer_cast<T>(convertJsonToASTNode(_node));
ASTPointer<T> ret = std::dynamic_pointer_cast<T>(convertJsonToASTNode(_node));
astAssert(ret, "cast of converted json-node must not be nullptr");
return ret;
}
@ -143,7 +141,7 @@ ASTPointer<T> ASTJsonImporter::convertJsonToASTNode(Json::Value const& _node)
ASTPointer<ASTNode> ASTJsonImporter::convertJsonToASTNode(Json::Value const& _json)
{
astAssert(_json["nodeType"].isString() && _json.isMember("id"), "JSON-Node needs to have 'nodeType' and 'id' fields.");
string nodeType = _json["nodeType"].asString();
std::string nodeType = _json["nodeType"].asString();
if (nodeType == "PragmaDirective")
return createPragmaDirective(_json);
if (nodeType == "ImportDirective")
@ -265,9 +263,9 @@ ASTPointer<ASTNode> ASTJsonImporter::convertJsonToASTNode(Json::Value const& _js
// ============ functions to instantiate the AST-Nodes from Json-Nodes ==============
ASTPointer<SourceUnit> ASTJsonImporter::createSourceUnit(Json::Value const& _node, string const& _srcName)
ASTPointer<SourceUnit> ASTJsonImporter::createSourceUnit(Json::Value const& _node, std::string const& _srcName)
{
optional<string> license;
std::optional<std::string> license;
if (_node.isMember("license") && !_node["license"].isNull())
license = _node["license"].asString();
@ -275,7 +273,7 @@ ASTPointer<SourceUnit> ASTJsonImporter::createSourceUnit(Json::Value const& _nod
if (_node.isMember("experimentalSolidity") && !_node["experimentalSolidity"].isNull())
experimentalSolidity = _node["experimentalSolidity"].asBool();
vector<ASTPointer<ASTNode>> nodes;
std::vector<ASTPointer<ASTNode>> nodes;
for (auto& child: member(_node, "nodes"))
nodes.emplace_back(convertJsonToASTNode(child));
@ -286,11 +284,11 @@ ASTPointer<SourceUnit> ASTJsonImporter::createSourceUnit(Json::Value const& _nod
ASTPointer<PragmaDirective> ASTJsonImporter::createPragmaDirective(Json::Value const& _node)
{
vector<Token> tokens;
vector<ASTString> literals;
std::vector<Token> tokens;
std::vector<ASTString> literals;
for (auto const& lit: member(_node, "literals"))
{
string l = lit.asString();
std::string l = lit.asString();
literals.push_back(l);
tokens.push_back(scanSingleToken(l));
}
@ -309,7 +307,7 @@ ASTPointer<ImportDirective> ASTJsonImporter::createImportDirective(Json::Value c
symbolAliases.push_back({
createIdentifier(tuple["foreign"]),
tuple["local"].isNull() ? nullptr : make_shared<ASTString>(tuple["local"].asString()),
tuple["local"].isNull() ? nullptr : std::make_shared<ASTString>(tuple["local"].asString()),
createSourceLocation(tuple["foreign"])}
);
}
@ -343,7 +341,7 @@ ASTPointer<ContractDefinition> ASTJsonImporter::createContractDefinition(Json::V
return createASTNode<ContractDefinition>(
_node,
make_shared<ASTString>(_node["name"].asString()),
std::make_shared<ASTString>(_node["name"].asString()),
createNameSourceLocation(_node),
_node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")),
baseContracts,
@ -357,13 +355,13 @@ ASTPointer<IdentifierPath> ASTJsonImporter::createIdentifierPath(Json::Value con
{
astAssert(_node["name"].isString(), "Expected 'name' to be a string!");
vector<ASTString> namePath;
vector<SourceLocation> namePathLocations;
vector<string> strs;
string nameString = member(_node, "name").asString();
std::vector<ASTString> namePath;
std::vector<SourceLocation> namePathLocations;
std::vector<std::string> strs;
std::string nameString = member(_node, "name").asString();
boost::algorithm::split(strs, nameString, boost::is_any_of("."));
astAssert(!strs.empty(), "Expected at least one element in IdentifierPath.");
for (string s: strs)
for (std::string s: strs)
{
astAssert(!s.empty(), "Expected non-empty string for IdentifierPath element.");
namePath.emplace_back(s);
@ -395,20 +393,20 @@ ASTPointer<InheritanceSpecifier> ASTJsonImporter::createInheritanceSpecifier(Jso
return createASTNode<InheritanceSpecifier>(
_node,
createIdentifierPath(member(_node, "baseName")),
member(_node, "arguments").isNull() ? nullptr : make_unique<std::vector<ASTPointer<Expression>>>(arguments)
member(_node, "arguments").isNull() ? nullptr : std::make_unique<std::vector<ASTPointer<Expression>>>(arguments)
);
}
ASTPointer<UsingForDirective> ASTJsonImporter::createUsingForDirective(Json::Value const& _node)
{
vector<ASTPointer<IdentifierPath>> functions;
vector<optional<Token>> operators;
std::vector<ASTPointer<IdentifierPath>> functions;
std::vector<std::optional<Token>> operators;
if (_node.isMember("libraryName"))
{
astAssert(!_node["libraryName"].isArray());
astAssert(!_node["libraryName"]["operator"]);
functions.emplace_back(createIdentifierPath(_node["libraryName"]));
operators.emplace_back(nullopt);
operators.emplace_back(std::nullopt);
}
else if (_node.isMember("functionList"))
for (Json::Value const& function: _node["functionList"])
@ -419,7 +417,7 @@ ASTPointer<UsingForDirective> ASTJsonImporter::createUsingForDirective(Json::Val
astAssert(!function.isMember("definition"));
functions.emplace_back(createIdentifierPath(function["function"]));
operators.emplace_back(nullopt);
operators.emplace_back(std::nullopt);
}
else
{
@ -520,7 +518,7 @@ ASTPointer<FunctionDefinition> ASTJsonImporter::createFunctionDefinition(Json::V
Token kind;
bool freeFunction = false;
string kindStr = member(_node, "kind").asString();
std::string kindStr = member(_node, "kind").asString();
if (kindStr == "constructor")
kind = Token::Constructor;
@ -572,7 +570,7 @@ ASTPointer<VariableDeclaration> ASTJsonImporter::createVariableDeclaration(Json:
VariableDeclaration::Mutability mutability{};
astAssert(member(_node, "mutability").isString(), "'mutability' expected to be string.");
string const mutabilityStr = member(_node, "mutability").asString();
std::string const mutabilityStr = member(_node, "mutability").asString();
if (mutabilityStr == "constant")
{
mutability = VariableDeclaration::Mutability::Constant;
@ -592,7 +590,7 @@ ASTPointer<VariableDeclaration> ASTJsonImporter::createVariableDeclaration(Json:
return createASTNode<VariableDeclaration>(
_node,
nullOrCast<TypeName>(member(_node, "typeName")),
make_shared<ASTString>(member(_node, "name").asString()),
std::make_shared<ASTString>(member(_node, "name").asString()),
createNameSourceLocation(_node),
nullOrCast<Expression>(member(_node, "value")),
visibility(_node),
@ -626,7 +624,7 @@ ASTPointer<ModifierInvocation> ASTJsonImporter::createModifierInvocation(Json::V
return createASTNode<ModifierInvocation>(
_node,
createIdentifierPath(member(_node, "modifierName")),
member(_node, "arguments").isNull() ? nullptr : make_unique<std::vector<ASTPointer<Expression>>>(arguments)
member(_node, "arguments").isNull() ? nullptr : std::make_unique<std::vector<ASTPointer<Expression>>>(arguments)
);
}
@ -660,9 +658,9 @@ ASTPointer<ElementaryTypeName> ASTJsonImporter::createElementaryTypeName(Json::V
astAssert(_node["name"].isString(), "Expected 'name' to be a string!");
string name = member(_node, "name").asString();
std::string name = member(_node, "name").asString();
Token token;
tie(token, firstNum, secondNum) = TokenTraits::fromIdentifierOrKeyword(name);
std::tie(token, firstNum, secondNum) = TokenTraits::fromIdentifierOrKeyword(name);
ElementaryTypeNameToken elem(token, firstNum, secondNum);
std::optional<StateMutability> mutability = {};
@ -721,19 +719,19 @@ ASTPointer<InlineAssembly> ASTJsonImporter::createInlineAssembly(Json::Value con
astAssert(m_evmVersion == evmVersion, "Imported tree evm version differs from configured evm version!");
yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(evmVersion.value());
ASTPointer<vector<ASTPointer<ASTString>>> flags;
ASTPointer<std::vector<ASTPointer<ASTString>>> flags;
if (_node.isMember("flags"))
{
flags = make_shared<vector<ASTPointer<ASTString>>>();
flags = std::make_shared<std::vector<ASTPointer<ASTString>>>();
Json::Value const& flagsNode = _node["flags"];
astAssert(flagsNode.isArray(), "Assembly flags must be an array.");
for (Json::ArrayIndex i = 0; i < flagsNode.size(); ++i)
{
astAssert(flagsNode[i].isString(), "Assembly flag must be a string.");
flags->emplace_back(make_shared<ASTString>(flagsNode[i].asString()));
flags->emplace_back(std::make_shared<ASTString>(flagsNode[i].asString()));
}
}
shared_ptr<yul::Block> operations = make_shared<yul::Block>(yul::AsmJsonImporter(m_sourceNames).createBlock(member(_node, "AST")));
std::shared_ptr<yul::Block> operations = std::make_shared<yul::Block>(yul::AsmJsonImporter(m_sourceNames).createBlock(member(_node, "AST")));
return createASTNode<InlineAssembly>(
_node,
nullOrASTString(_node, "documentation"),
@ -787,7 +785,7 @@ ASTPointer<TryCatchClause> ASTJsonImporter::createTryCatchClause(Json::Value con
ASTPointer<TryStatement> ASTJsonImporter::createTryStatement(Json::Value const& _node)
{
vector<ASTPointer<TryCatchClause>> clauses;
std::vector<ASTPointer<TryCatchClause>> clauses;
for (auto& param: _node["clauses"])
clauses.emplace_back(createTryCatchClause(param));
@ -957,10 +955,10 @@ ASTPointer<FunctionCall> ASTJsonImporter::createFunctionCall(Json::Value const&
for (auto& name: member(_node, "names"))
{
astAssert(name.isString(), "Expected 'names' members to be strings!");
names.push_back(make_shared<ASTString>(name.asString()));
names.push_back(std::make_shared<ASTString>(name.asString()));
}
optional<vector<SourceLocation>> sourceLocations = createSourceLocations(_node);
std::optional<std::vector<SourceLocation>> sourceLocations = createSourceLocations(_node);
return createASTNode<FunctionCall>(
_node,
@ -969,7 +967,7 @@ ASTPointer<FunctionCall> ASTJsonImporter::createFunctionCall(Json::Value const&
names,
sourceLocations ?
*sourceLocations :
vector<SourceLocation>(names.size())
std::vector<SourceLocation>(names.size())
);
}
@ -982,7 +980,7 @@ ASTPointer<FunctionCallOptions> ASTJsonImporter::createFunctionCallOptions(Json:
for (auto& name: member(_node, "names"))
{
astAssert(name.isString(), "Expected 'names' members to be strings!");
names.push_back(make_shared<ASTString>(name.asString()));
names.push_back(std::make_shared<ASTString>(name.asString()));
}
return createASTNode<FunctionCallOptions>(
@ -1049,14 +1047,14 @@ ASTPointer<ElementaryTypeNameExpression> ASTJsonImporter::createElementaryTypeNa
ASTPointer<ASTNode> ASTJsonImporter::createLiteral(Json::Value const& _node)
{
static string const valStr = "value";
static string const hexValStr = "hexValue";
static std::string const valStr = "value";
static std::string const hexValStr = "hexValue";
astAssert(member(_node, valStr).isString() || member(_node, hexValStr).isString(), "Literal-value is unset.");
ASTPointer<ASTString> value = _node.isMember(hexValStr) ?
make_shared<ASTString>(util::asString(util::fromHex(_node[hexValStr].asString()))) :
make_shared<ASTString>(_node[valStr].asString());
std::make_shared<ASTString>(util::asString(util::fromHex(_node[hexValStr].asString()))) :
std::make_shared<ASTString>(_node[valStr].asString());
return createASTNode<Literal>(
_node,
@ -1068,19 +1066,19 @@ ASTPointer<ASTNode> ASTJsonImporter::createLiteral(Json::Value const& _node)
ASTPointer<StructuredDocumentation> ASTJsonImporter::createDocumentation(Json::Value const& _node)
{
static string const textString = "text";
static std::string const textString = "text";
astAssert(member(_node, textString).isString(), "'text' must be a string");
return createASTNode<StructuredDocumentation>(
_node,
make_shared<ASTString>(_node[textString].asString())
std::make_shared<ASTString>(_node[textString].asString())
);
}
// ===== helper functions ==========
Json::Value ASTJsonImporter::member(Json::Value const& _node, string const& _name)
Json::Value ASTJsonImporter::member(Json::Value const& _node, std::string const& _name)
{
if (!_node.isMember(_name))
return Json::nullValue;
@ -1095,19 +1093,19 @@ Token ASTJsonImporter::scanSingleToken(Json::Value const& _node)
return scanner.currentToken();
}
ASTPointer<ASTString> ASTJsonImporter::nullOrASTString(Json::Value const& _json, string const& _name)
ASTPointer<ASTString> ASTJsonImporter::nullOrASTString(Json::Value const& _json, std::string const& _name)
{
return _json[_name].isString() ? memberAsASTString(_json, _name) : nullptr;
}
ASTPointer<ASTString> ASTJsonImporter::memberAsASTString(Json::Value const& _node, string const& _name)
ASTPointer<ASTString> ASTJsonImporter::memberAsASTString(Json::Value const& _node, std::string const& _name)
{
Json::Value value = member(_node, _name);
astAssert(value.isString(), "field " + _name + " must be of type string.");
return make_shared<ASTString>(_node[_name].asString());
return std::make_shared<ASTString>(_node[_name].asString());
}
bool ASTJsonImporter::memberAsBool(Json::Value const& _node, string const& _name)
bool ASTJsonImporter::memberAsBool(Json::Value const& _node, std::string const& _name)
{
Json::Value value = member(_node, _name);
astAssert(value.isBool(), "field " + _name + " must be of type boolean.");
@ -1156,7 +1154,7 @@ Visibility ASTJsonImporter::visibility(Json::Value const& _node)
Json::Value visibility = member(_node, "visibility");
astAssert(visibility.isString(), "'visibility' expected to be a string.");
string const visibilityStr = visibility.asString();
std::string const visibilityStr = visibility.asString();
if (visibilityStr == "default")
return Visibility::Default;
@ -1180,7 +1178,7 @@ VariableDeclaration::Location ASTJsonImporter::location(Json::Value const& _node
Json::Value storageLoc = member(_node, "storageLocation");
astAssert(storageLoc.isString(), "'storageLocation' expected to be a string.");
string const storageLocStr = storageLoc.asString();
std::string const storageLocStr = storageLoc.asString();
if (storageLocStr == "default")
return VariableDeclaration::Location::Unspecified;
@ -1206,7 +1204,7 @@ Literal::SubDenomination ASTJsonImporter::subdenomination(Json::Value const& _no
astAssert(subDen.isString(), "'subDenomination' expected to be string.");
string const subDenStr = subDen.asString();
std::string const subDenStr = subDen.asString();
if (subDenStr == "wei")
return Literal::SubDenomination::Wei;
@ -1236,7 +1234,7 @@ Literal::SubDenomination ASTJsonImporter::subdenomination(Json::Value const& _no
StateMutability ASTJsonImporter::stateMutability(Json::Value const& _node)
{
astAssert(member(_node, "stateMutability").isString(), "StateMutability' expected to be string.");
string const mutabilityStr = member(_node, "stateMutability").asString();
std::string const mutabilityStr = member(_node, "stateMutability").asString();
if (mutabilityStr == "pure")
return StateMutability::Pure;

View File

@ -18,7 +18,6 @@
#include <libsolidity/ast/CallGraph.h>
using namespace std;
using namespace solidity::frontend;
bool CallGraph::CompareByID::operator()(Node const& _lhs, Node const& _rhs) const
@ -26,21 +25,21 @@ bool CallGraph::CompareByID::operator()(Node const& _lhs, Node const& _rhs) cons
if (_lhs.index() != _rhs.index())
return _lhs.index() < _rhs.index();
if (holds_alternative<SpecialNode>(_lhs))
return get<SpecialNode>(_lhs) < get<SpecialNode>(_rhs);
return get<CallableDeclaration const*>(_lhs)->id() < get<CallableDeclaration const*>(_rhs)->id();
if (std::holds_alternative<SpecialNode>(_lhs))
return std::get<SpecialNode>(_lhs) < std::get<SpecialNode>(_rhs);
return std::get<CallableDeclaration const*>(_lhs)->id() < std::get<CallableDeclaration const*>(_rhs)->id();
}
bool CallGraph::CompareByID::operator()(Node const& _lhs, int64_t _rhs) const
{
solAssert(!holds_alternative<SpecialNode>(_lhs), "");
solAssert(!std::holds_alternative<SpecialNode>(_lhs), "");
return get<CallableDeclaration const*>(_lhs)->id() < _rhs;
return std::get<CallableDeclaration const*>(_lhs)->id() < _rhs;
}
bool CallGraph::CompareByID::operator()(int64_t _lhs, Node const& _rhs) const
{
solAssert(!holds_alternative<SpecialNode>(_rhs), "");
solAssert(!std::holds_alternative<SpecialNode>(_rhs), "");
return _lhs < get<CallableDeclaration const*>(_rhs)->id();
return _lhs < std::get<CallableDeclaration const*>(_rhs)->id();
}

View File

@ -21,7 +21,6 @@
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
using namespace solidity::util;
@ -31,126 +30,126 @@ InaccessibleDynamicType const TypeProvider::m_inaccessibleDynamic{};
/// The string and bytes unique_ptrs are initialized when they are first used because
/// they rely on `byte` being available which we cannot guarantee in the static init context.
unique_ptr<ArrayType> TypeProvider::m_bytesStorage;
unique_ptr<ArrayType> TypeProvider::m_bytesMemory;
unique_ptr<ArrayType> TypeProvider::m_bytesCalldata;
unique_ptr<ArrayType> TypeProvider::m_stringStorage;
unique_ptr<ArrayType> TypeProvider::m_stringMemory;
std::unique_ptr<ArrayType> TypeProvider::m_bytesStorage;
std::unique_ptr<ArrayType> TypeProvider::m_bytesMemory;
std::unique_ptr<ArrayType> TypeProvider::m_bytesCalldata;
std::unique_ptr<ArrayType> TypeProvider::m_stringStorage;
std::unique_ptr<ArrayType> TypeProvider::m_stringMemory;
TupleType const TypeProvider::m_emptyTuple{};
AddressType const TypeProvider::m_payableAddress{StateMutability::Payable};
AddressType const TypeProvider::m_address{StateMutability::NonPayable};
array<unique_ptr<IntegerType>, 32> const TypeProvider::m_intM{{
{make_unique<IntegerType>(8 * 1, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 2, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 3, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 4, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 5, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 6, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 7, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 8, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 9, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 10, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 11, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 12, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 13, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 14, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 15, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 16, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 17, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 18, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 19, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 20, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 21, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 22, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 23, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 24, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 25, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 26, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 27, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 28, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 29, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 30, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 31, IntegerType::Modifier::Signed)},
{make_unique<IntegerType>(8 * 32, IntegerType::Modifier::Signed)}
std::array<std::unique_ptr<IntegerType>, 32> const TypeProvider::m_intM{{
{std::make_unique<IntegerType>(8 * 1, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 2, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 3, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 4, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 5, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 6, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 7, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 8, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 9, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 10, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 11, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 12, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 13, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 14, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 15, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 16, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 17, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 18, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 19, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 20, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 21, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 22, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 23, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 24, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 25, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 26, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 27, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 28, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 29, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 30, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 31, IntegerType::Modifier::Signed)},
{std::make_unique<IntegerType>(8 * 32, IntegerType::Modifier::Signed)}
}};
array<unique_ptr<IntegerType>, 32> const TypeProvider::m_uintM{{
{make_unique<IntegerType>(8 * 1, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 2, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 3, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 4, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 5, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 6, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 7, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 8, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 9, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 10, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 11, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 12, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 13, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 14, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 15, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 16, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 17, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 18, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 19, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 20, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 21, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 22, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 23, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 24, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 25, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 26, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 27, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 28, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 29, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 30, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 31, IntegerType::Modifier::Unsigned)},
{make_unique<IntegerType>(8 * 32, IntegerType::Modifier::Unsigned)}
std::array<std::unique_ptr<IntegerType>, 32> const TypeProvider::m_uintM{{
{std::make_unique<IntegerType>(8 * 1, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 2, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 3, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 4, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 5, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 6, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 7, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 8, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 9, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 10, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 11, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 12, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 13, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 14, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 15, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 16, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 17, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 18, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 19, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 20, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 21, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 22, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 23, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 24, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 25, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 26, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 27, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 28, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 29, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 30, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 31, IntegerType::Modifier::Unsigned)},
{std::make_unique<IntegerType>(8 * 32, IntegerType::Modifier::Unsigned)}
}};
array<unique_ptr<FixedBytesType>, 32> const TypeProvider::m_bytesM{{
{make_unique<FixedBytesType>(1)},
{make_unique<FixedBytesType>(2)},
{make_unique<FixedBytesType>(3)},
{make_unique<FixedBytesType>(4)},
{make_unique<FixedBytesType>(5)},
{make_unique<FixedBytesType>(6)},
{make_unique<FixedBytesType>(7)},
{make_unique<FixedBytesType>(8)},
{make_unique<FixedBytesType>(9)},
{make_unique<FixedBytesType>(10)},
{make_unique<FixedBytesType>(11)},
{make_unique<FixedBytesType>(12)},
{make_unique<FixedBytesType>(13)},
{make_unique<FixedBytesType>(14)},
{make_unique<FixedBytesType>(15)},
{make_unique<FixedBytesType>(16)},
{make_unique<FixedBytesType>(17)},
{make_unique<FixedBytesType>(18)},
{make_unique<FixedBytesType>(19)},
{make_unique<FixedBytesType>(20)},
{make_unique<FixedBytesType>(21)},
{make_unique<FixedBytesType>(22)},
{make_unique<FixedBytesType>(23)},
{make_unique<FixedBytesType>(24)},
{make_unique<FixedBytesType>(25)},
{make_unique<FixedBytesType>(26)},
{make_unique<FixedBytesType>(27)},
{make_unique<FixedBytesType>(28)},
{make_unique<FixedBytesType>(29)},
{make_unique<FixedBytesType>(30)},
{make_unique<FixedBytesType>(31)},
{make_unique<FixedBytesType>(32)}
std::array<std::unique_ptr<FixedBytesType>, 32> const TypeProvider::m_bytesM{{
{std::make_unique<FixedBytesType>(1)},
{std::make_unique<FixedBytesType>(2)},
{std::make_unique<FixedBytesType>(3)},
{std::make_unique<FixedBytesType>(4)},
{std::make_unique<FixedBytesType>(5)},
{std::make_unique<FixedBytesType>(6)},
{std::make_unique<FixedBytesType>(7)},
{std::make_unique<FixedBytesType>(8)},
{std::make_unique<FixedBytesType>(9)},
{std::make_unique<FixedBytesType>(10)},
{std::make_unique<FixedBytesType>(11)},
{std::make_unique<FixedBytesType>(12)},
{std::make_unique<FixedBytesType>(13)},
{std::make_unique<FixedBytesType>(14)},
{std::make_unique<FixedBytesType>(15)},
{std::make_unique<FixedBytesType>(16)},
{std::make_unique<FixedBytesType>(17)},
{std::make_unique<FixedBytesType>(18)},
{std::make_unique<FixedBytesType>(19)},
{std::make_unique<FixedBytesType>(20)},
{std::make_unique<FixedBytesType>(21)},
{std::make_unique<FixedBytesType>(22)},
{std::make_unique<FixedBytesType>(23)},
{std::make_unique<FixedBytesType>(24)},
{std::make_unique<FixedBytesType>(25)},
{std::make_unique<FixedBytesType>(26)},
{std::make_unique<FixedBytesType>(27)},
{std::make_unique<FixedBytesType>(28)},
{std::make_unique<FixedBytesType>(29)},
{std::make_unique<FixedBytesType>(30)},
{std::make_unique<FixedBytesType>(31)},
{std::make_unique<FixedBytesType>(32)}
}};
array<unique_ptr<MagicType>, 4> const TypeProvider::m_magics{{
{make_unique<MagicType>(MagicType::Kind::Block)},
{make_unique<MagicType>(MagicType::Kind::Message)},
{make_unique<MagicType>(MagicType::Kind::Transaction)},
{make_unique<MagicType>(MagicType::Kind::ABI)}
std::array<std::unique_ptr<MagicType>, 4> const TypeProvider::m_magics{{
{std::make_unique<MagicType>(MagicType::Kind::Block)},
{std::make_unique<MagicType>(MagicType::Kind::Message)},
{std::make_unique<MagicType>(MagicType::Kind::Transaction)},
{std::make_unique<MagicType>(MagicType::Kind::ABI)}
// MetaType is stored separately
}};
@ -160,7 +159,7 @@ inline void clearCache(Type const& type)
}
template <typename T>
inline void clearCache(unique_ptr<T> const& type)
inline void clearCache(std::unique_ptr<T> const& type)
{
// Some lazy-initialized types might not exist yet.
if (type)
@ -200,7 +199,7 @@ void TypeProvider::reset()
template <typename T, typename... Args>
inline T const* TypeProvider::createAndGet(Args&& ... _args)
{
instance().m_generalTypes.emplace_back(make_unique<T>(std::forward<Args>(_args)...));
instance().m_generalTypes.emplace_back(std::make_unique<T>(std::forward<Args>(_args)...));
return static_cast<T const*>(instance().m_generalTypes.back().get());
}
@ -259,15 +258,15 @@ Type const* TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken const&
}
}
Type const* TypeProvider::fromElementaryTypeName(string const& _name)
Type const* TypeProvider::fromElementaryTypeName(std::string const& _name)
{
vector<string> nameParts;
std::vector<std::string> nameParts;
boost::split(nameParts, _name, boost::is_any_of(" "));
solAssert(nameParts.size() == 1 || nameParts.size() == 2, "Cannot parse elementary type: " + _name);
Token token;
unsigned short firstNum, secondNum;
tie(token, firstNum, secondNum) = TokenTraits::fromIdentifierOrKeyword(nameParts[0]);
std::tie(token, firstNum, secondNum) = TokenTraits::fromIdentifierOrKeyword(nameParts[0]);
auto t = fromElementaryTypeName(ElementaryTypeNameToken(token, firstNum, secondNum));
if (auto* ref = dynamic_cast<ReferenceType const*>(t))
@ -307,35 +306,35 @@ Type const* TypeProvider::fromElementaryTypeName(string const& _name)
ArrayType const* TypeProvider::bytesStorage()
{
if (!m_bytesStorage)
m_bytesStorage = make_unique<ArrayType>(DataLocation::Storage, false);
m_bytesStorage = std::make_unique<ArrayType>(DataLocation::Storage, false);
return m_bytesStorage.get();
}
ArrayType const* TypeProvider::bytesMemory()
{
if (!m_bytesMemory)
m_bytesMemory = make_unique<ArrayType>(DataLocation::Memory, false);
m_bytesMemory = std::make_unique<ArrayType>(DataLocation::Memory, false);
return m_bytesMemory.get();
}
ArrayType const* TypeProvider::bytesCalldata()
{
if (!m_bytesCalldata)
m_bytesCalldata = make_unique<ArrayType>(DataLocation::CallData, false);
m_bytesCalldata = std::make_unique<ArrayType>(DataLocation::CallData, false);
return m_bytesCalldata.get();
}
ArrayType const* TypeProvider::stringStorage()
{
if (!m_stringStorage)
m_stringStorage = make_unique<ArrayType>(DataLocation::Storage, true);
m_stringStorage = std::make_unique<ArrayType>(DataLocation::Storage, true);
return m_stringStorage.get();
}
ArrayType const* TypeProvider::stringMemory()
{
if (!m_stringMemory)
m_stringMemory = make_unique<ArrayType>(DataLocation::Memory, true);
m_stringMemory = std::make_unique<ArrayType>(DataLocation::Memory, true);
return m_stringMemory.get();
}
@ -376,30 +375,30 @@ RationalNumberType const* TypeProvider::rationalNumber(Literal const& _literal)
return nullptr;
}
StringLiteralType const* TypeProvider::stringLiteral(string const& literal)
StringLiteralType const* TypeProvider::stringLiteral(std::string const& literal)
{
auto i = instance().m_stringLiteralTypes.find(literal);
if (i != instance().m_stringLiteralTypes.end())
return i->second.get();
else
return instance().m_stringLiteralTypes.emplace(literal, make_unique<StringLiteralType>(literal)).first->second.get();
return instance().m_stringLiteralTypes.emplace(literal, std::make_unique<StringLiteralType>(literal)).first->second.get();
}
FixedPointType const* TypeProvider::fixedPoint(unsigned m, unsigned n, FixedPointType::Modifier _modifier)
{
auto& map = _modifier == FixedPointType::Modifier::Unsigned ? instance().m_ufixedMxN : instance().m_fixedMxN;
auto i = map.find(make_pair(m, n));
auto i = map.find(std::make_pair(m, n));
if (i != map.end())
return i->second.get();
return map.emplace(
make_pair(m, n),
make_unique<FixedPointType>(m, n, _modifier)
std::make_pair(m, n),
std::make_unique<FixedPointType>(m, n, _modifier)
).first->second.get();
}
TupleType const* TypeProvider::tuple(vector<Type const*> members)
TupleType const* TypeProvider::tuple(std::vector<Type const*> members)
{
if (members.empty())
return &m_emptyTuple;

File diff suppressed because it is too large Load Diff

View File

@ -30,12 +30,11 @@
#include <boost/algorithm/string/join.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::frontend;
string ABIFunctions::tupleEncoder(
std::string ABIFunctions::tupleEncoder(
TypePointers const& _givenTypes,
TypePointers _targetTypes,
bool _encodeAsLibraryTypes,
@ -56,7 +55,7 @@ string ABIFunctions::tupleEncoder(
solAssert(t, "");
}
string functionName = string("abi_encode_tuple_");
std::string functionName = std::string("abi_encode_tuple_");
for (auto const& t: _givenTypes)
functionName += t->identifier() + "_";
functionName += "_to_";
@ -76,8 +75,8 @@ string ABIFunctions::tupleEncoder(
)");
templ("functionName", functionName);
size_t const headSize_ = headSize(_targetTypes);
templ("headSize", to_string(headSize_));
string encodeElements;
templ("headSize", std::to_string(headSize_));
std::string encodeElements;
size_t headPos = 0;
size_t stackPos = 0;
for (size_t i = 0; i < _givenTypes.size(); ++i)
@ -88,24 +87,24 @@ string ABIFunctions::tupleEncoder(
bool dynamic = _targetTypes[i]->isDynamicallyEncoded();
Whiskers elementTempl(
dynamic ?
string(R"(
std::string(R"(
mstore(add(headStart, <pos>), sub(tail, headStart))
tail := <abiEncode>(<values> tail)
)") :
string(R"(
std::string(R"(
<abiEncode>(<values> add(headStart, <pos>))
)")
);
string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack);
std::string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack);
elementTempl("values", values.empty() ? "" : values + ", ");
elementTempl("pos", to_string(headPos));
elementTempl("pos", std::to_string(headPos));
elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], options));
encodeElements += elementTempl.render();
headPos += _targetTypes[i]->calldataHeadSize();
stackPos += sizeOnStack;
}
solAssert(headPos == headSize_, "");
string valueParams =
std::string valueParams =
_reversed ?
suffixedVariableNameList("value", stackPos, 0) :
suffixedVariableNameList("value", 0, stackPos);
@ -116,7 +115,7 @@ string ABIFunctions::tupleEncoder(
});
}
string ABIFunctions::tupleEncoderPacked(
std::string ABIFunctions::tupleEncoderPacked(
TypePointers const& _givenTypes,
TypePointers _targetTypes,
bool _reversed
@ -135,7 +134,7 @@ string ABIFunctions::tupleEncoderPacked(
solAssert(t, "");
}
string functionName = string("abi_encode_tuple_packed_");
std::string functionName = std::string("abi_encode_tuple_packed_");
for (auto const& t: _givenTypes)
functionName += t->identifier() + "_";
functionName += "_to_";
@ -154,7 +153,7 @@ string ABIFunctions::tupleEncoderPacked(
}
)");
templ("functionName", functionName);
string encodeElements;
std::string encodeElements;
size_t stackPos = 0;
for (size_t i = 0; i < _givenTypes.size(); ++i)
{
@ -164,23 +163,23 @@ string ABIFunctions::tupleEncoderPacked(
bool dynamic = _targetTypes[i]->isDynamicallyEncoded();
Whiskers elementTempl(
dynamic ?
string(R"(
std::string(R"(
pos := <abiEncode>(<values> pos)
)") :
string(R"(
std::string(R"(
<abiEncode>(<values> pos)
pos := add(pos, <calldataEncodedSize>)
)")
);
string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack);
std::string values = suffixedVariableNameList("value", stackPos, stackPos + sizeOnStack);
elementTempl("values", values.empty() ? "" : values + ", ");
if (!dynamic)
elementTempl("calldataEncodedSize", to_string(_targetTypes[i]->calldataEncodedSize(false)));
elementTempl("calldataEncodedSize", std::to_string(_targetTypes[i]->calldataEncodedSize(false)));
elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], options));
encodeElements += elementTempl.render();
stackPos += sizeOnStack;
}
string valueParams =
std::string valueParams =
_reversed ?
suffixedVariableNameList("value", stackPos, 0) :
suffixedVariableNameList("value", 0, stackPos);
@ -190,9 +189,9 @@ string ABIFunctions::tupleEncoderPacked(
return templ.render();
});
}
string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)
std::string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)
{
string functionName = string("abi_decode_tuple_");
std::string functionName = std::string("abi_decode_tuple_");
for (auto const& t: _types)
functionName += t->identifier();
if (_fromMemory)
@ -211,10 +210,10 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)
)");
templ("functionName", functionName);
templ("revertString", revertReasonIfDebugFunction("ABI decoding: tuple data too short"));
templ("minimumSize", to_string(headSize(decodingTypes)));
templ("minimumSize", std::to_string(headSize(decodingTypes)));
string decodeElements;
vector<string> valueReturnParams;
std::string decodeElements;
std::vector<std::string> valueReturnParams;
size_t headPos = 0;
size_t stackPos = 0;
for (size_t i = 0; i < _types.size(); ++i)
@ -224,11 +223,11 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)
size_t sizeOnStack = _types[i]->sizeOnStack();
solAssert(sizeOnStack == decodingTypes[i]->sizeOnStack(), "");
solAssert(sizeOnStack > 0, "");
vector<string> valueNamesLocal;
std::vector<std::string> valueNamesLocal;
for (size_t j = 0; j < sizeOnStack; j++)
{
valueNamesLocal.emplace_back("value" + to_string(stackPos));
valueReturnParams.emplace_back("value" + to_string(stackPos));
valueNamesLocal.emplace_back("value" + std::to_string(stackPos));
valueReturnParams.emplace_back("value" + std::to_string(stackPos));
stackPos++;
}
Whiskers elementTempl(R"(
@ -247,7 +246,7 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)
elementTempl("revertString", revertReasonIfDebugFunction("ABI decoding: invalid tuple offset"));
elementTempl("load", _fromMemory ? "mload" : "calldataload");
elementTempl("values", boost::algorithm::join(valueNamesLocal, ", "));
elementTempl("pos", to_string(headPos));
elementTempl("pos", std::to_string(headPos));
elementTempl("abiDecode", abiDecodingFunction(*_types[i], _fromMemory, true));
decodeElements += elementTempl.render();
headPos += decodingTypes[i]->calldataHeadSize();
@ -260,9 +259,9 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)
});
}
string ABIFunctions::EncodingOptions::toFunctionNameSuffix() const
std::string ABIFunctions::EncodingOptions::toFunctionNameSuffix() const
{
string suffix;
std::string suffix;
if (!padded)
suffix += "_nonPadded";
if (dynamicInplace)
@ -274,7 +273,7 @@ string ABIFunctions::EncodingOptions::toFunctionNameSuffix() const
return suffix;
}
string ABIFunctions::abiEncodingFunction(
std::string ABIFunctions::abiEncodingFunction(
Type const& _from,
Type const& _to,
EncodingOptions const& _options
@ -349,7 +348,7 @@ string ABIFunctions::abiEncodingFunction(
solAssert(_from.sizeOnStack() == 1, "");
solAssert(to.isValueType(), "");
solAssert(to.calldataEncodedSize() == 32, "");
string functionName =
std::string functionName =
"abi_encode_" +
_from.identifier() +
"_to_" +
@ -376,7 +375,7 @@ string ABIFunctions::abiEncodingFunction(
}
else
{
string cleanupConvert;
std::string cleanupConvert;
if (_from == to)
cleanupConvert = m_utils.cleanupFunction(_from) + "(value)";
else
@ -389,21 +388,21 @@ string ABIFunctions::abiEncodingFunction(
});
}
string ABIFunctions::abiEncodeAndReturnUpdatedPosFunction(
std::string ABIFunctions::abiEncodeAndReturnUpdatedPosFunction(
Type const& _givenType,
Type const& _targetType,
ABIFunctions::EncodingOptions const& _options
)
{
string functionName =
std::string functionName =
"abi_encodeUpdatedPos_" +
_givenType.identifier() +
"_to_" +
_targetType.identifier() +
_options.toFunctionNameSuffix();
return createFunction(functionName, [&]() {
string values = suffixedVariableNameList("value", 0, numVariablesForType(_givenType, _options));
string encoder = abiEncodingFunction(_givenType, _targetType, _options);
std::string values = suffixedVariableNameList("value", 0, numVariablesForType(_givenType, _options));
std::string encoder = abiEncodingFunction(_givenType, _targetType, _options);
Type const* targetEncoding = _targetType.fullEncodingType(_options.encodeAsLibraryTypes, true, false);
solAssert(targetEncoding, "");
if (targetEncoding->isDynamicallyEncoded())
@ -435,7 +434,7 @@ string ABIFunctions::abiEncodeAndReturnUpdatedPosFunction(
});
}
string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup(
std::string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup(
Type const& _from,
Type const& _to,
EncodingOptions const& _options
@ -461,7 +460,7 @@ string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup(
""
);
string functionName =
std::string functionName =
"abi_encode_" +
_from.identifier() +
"_to_" +
@ -522,13 +521,13 @@ string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup(
});
}
string ABIFunctions::abiEncodingFunctionSimpleArray(
std::string ABIFunctions::abiEncodingFunctionSimpleArray(
ArrayType const& _from,
ArrayType const& _to,
EncodingOptions const& _options
)
{
string functionName =
std::string functionName =
"abi_encode_" +
_from.identifier() +
"_to_" +
@ -548,7 +547,7 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
EncodingOptions subOptions(_options);
subOptions.encodeFunctionFromStack = false;
subOptions.padded = true;
string elementValues = suffixedVariableNameList("elementValue", 0, numVariablesForType(*_from.baseType(), subOptions));
std::string elementValues = suffixedVariableNameList("elementValue", 0, numVariablesForType(*_from.baseType(), subOptions));
Whiskers templ(
usesTail ?
R"(
@ -632,13 +631,13 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
});
}
string ABIFunctions::abiEncodingFunctionMemoryByteArray(
std::string ABIFunctions::abiEncodingFunctionMemoryByteArray(
ArrayType const& _from,
ArrayType const& _to,
EncodingOptions const& _options
)
{
string functionName =
std::string functionName =
"abi_encode_" +
_from.identifier() +
"_to_" +
@ -669,13 +668,13 @@ string ABIFunctions::abiEncodingFunctionMemoryByteArray(
});
}
string ABIFunctions::abiEncodingFunctionCompactStorageArray(
std::string ABIFunctions::abiEncodingFunctionCompactStorageArray(
ArrayType const& _from,
ArrayType const& _to,
EncodingOptions const& _options
)
{
string functionName =
std::string functionName =
"abi_encode_" +
_from.identifier() +
"_to_" +
@ -791,13 +790,13 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
templ("useSpill", "1");
else
templ("useSpill", "0");
templ("itemsPerSlot", to_string(itemsPerSlot));
templ("itemsPerSlot", std::to_string(itemsPerSlot));
templ("stride", toCompactHexWithPrefix(_to.calldataStride()));
EncodingOptions subOptions(_options);
subOptions.encodeFunctionFromStack = false;
subOptions.padded = true;
string encodeToMemoryFun = abiEncodingFunction(
std::string encodeToMemoryFun = abiEncodingFunction(
*_from.baseType(),
*_to.baseType(),
subOptions
@ -820,13 +819,13 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
});
}
string ABIFunctions::abiEncodingFunctionStruct(
std::string ABIFunctions::abiEncodingFunctionStruct(
StructType const& _from,
StructType const& _to,
EncodingOptions const& _options
)
{
string functionName =
std::string functionName =
"abi_encode_" +
_from.identifier() +
"_to_" +
@ -867,7 +866,7 @@ string ABIFunctions::abiEncodingFunctionStruct(
templ("init", _from.dataStoredIn(DataLocation::Storage) ? "let slotValue := 0" : "");
u256 previousSlotOffset(-1);
u256 encodingOffset = 0;
vector<map<string, string>> members;
std::vector<std::map<std::string, std::string>> members;
for (auto const& member: _to.members(nullptr))
{
solAssert(member.type, "");
@ -890,7 +889,7 @@ string ABIFunctions::abiEncodingFunctionStruct(
solAssert(memberTypeFrom->isValueType() == memberTypeTo->isValueType(), "");
u256 storageSlotOffset;
size_t intraSlotOffset;
tie(storageSlotOffset, intraSlotOffset) = _from.storageOffsetsOfMember(member.name);
std::tie(storageSlotOffset, intraSlotOffset) = _from.storageOffsetsOfMember(member.name);
if (memberTypeFrom->isValueType())
{
if (storageSlotOffset != previousSlotOffset)
@ -910,13 +909,13 @@ string ABIFunctions::abiEncodingFunctionStruct(
}
case DataLocation::Memory:
{
string sourceOffset = toCompactHexWithPrefix(_from.memoryOffsetOfMember(member.name));
std::string sourceOffset = toCompactHexWithPrefix(_from.memoryOffsetOfMember(member.name));
members.back()["retrieveValue"] = "mload(add(value, " + sourceOffset + "))";
break;
}
case DataLocation::CallData:
{
string sourceOffset = toCompactHexWithPrefix(_from.calldataOffsetOfMember(member.name));
std::string sourceOffset = toCompactHexWithPrefix(_from.calldataOffsetOfMember(member.name));
members.back()["retrieveValue"] = calldataAccessFunction(*memberTypeFrom) + "(value, add(value, " + sourceOffset + "))";
break;
}
@ -929,10 +928,10 @@ string ABIFunctions::abiEncodingFunctionStruct(
// Like with arrays, struct members are always padded.
subOptions.padded = true;
string memberValues = suffixedVariableNameList("memberValue", 0, numVariablesForType(*memberTypeFrom, subOptions));
std::string memberValues = suffixedVariableNameList("memberValue", 0, numVariablesForType(*memberTypeFrom, subOptions));
members.back()["memberValues"] = memberValues;
string encode;
std::string encode;
if (_options.dynamicInplace)
encode = Whiskers{"pos := <encode>(<memberValues>, pos)"}
("encode", abiEncodeAndReturnUpdatedPosFunction(*memberTypeFrom, *memberTypeTo, subOptions))
@ -942,7 +941,7 @@ string ABIFunctions::abiEncodingFunctionStruct(
{
Whiskers encodeTempl(
dynamicMember ?
string(R"(
std::string(R"(
mstore(add(pos, <encodingOffset>), sub(tail, pos))
tail := <abiEncode>(<memberValues>, tail)
)") :
@ -966,7 +965,7 @@ string ABIFunctions::abiEncodingFunctionStruct(
});
}
string ABIFunctions::abiEncodingFunctionStringLiteral(
std::string ABIFunctions::abiEncodingFunctionStringLiteral(
Type const& _from,
Type const& _to,
EncodingOptions const& _options
@ -974,7 +973,7 @@ string ABIFunctions::abiEncodingFunctionStringLiteral(
{
solAssert(_from.category() == Type::Category::StringLiteral, "");
string functionName =
std::string functionName =
"abi_encode_" +
_from.identifier() +
"_to_" +
@ -982,7 +981,7 @@ string ABIFunctions::abiEncodingFunctionStringLiteral(
_options.toFunctionNameSuffix();
return createFunction(functionName, [&]() {
auto const& strType = dynamic_cast<StringLiteralType const&>(_from);
string const& value = strType.value();
std::string const& value = strType.value();
solAssert(_from.sizeOnStack() == 0, "");
if (_to.isDynamicallySized())
@ -998,12 +997,12 @@ string ABIFunctions::abiEncodingFunctionStringLiteral(
templ("functionName", functionName);
// TODO this can make use of CODECOPY for large strings once we have that in Yul
templ("length", to_string(value.size()));
templ("length", std::to_string(value.size()));
templ("storeLength", arrayStoreLengthForEncodingFunction(dynamic_cast<ArrayType const&>(_to), _options));
if (_options.padded)
templ("overallSize", to_string(((value.size() + 31) / 32) * 32));
templ("overallSize", std::to_string(((value.size() + 31) / 32) * 32));
else
templ("overallSize", to_string(value.size()));
templ("overallSize", std::to_string(value.size()));
templ("storeLiteralInMemory", m_utils.storeLiteralInMemoryFunction(value));
return templ.render();
}
@ -1023,7 +1022,7 @@ string ABIFunctions::abiEncodingFunctionStringLiteral(
});
}
string ABIFunctions::abiEncodingFunctionFunctionType(
std::string ABIFunctions::abiEncodingFunctionFunctionType(
FunctionType const& _from,
Type const& _to,
EncodingOptions const& _options
@ -1036,7 +1035,7 @@ string ABIFunctions::abiEncodingFunctionFunctionType(
"Invalid function type conversion requested"
);
string functionName =
std::string functionName =
"abi_encode_" +
_from.identifier() +
"_to_" +
@ -1069,7 +1068,7 @@ string ABIFunctions::abiEncodingFunctionFunctionType(
});
}
string ABIFunctions::abiDecodingFunction(Type const& _type, bool _fromMemory, bool _forUseOnStack)
std::string ABIFunctions::abiDecodingFunction(Type const& _type, bool _fromMemory, bool _forUseOnStack)
{
// The decoding function has to perform bounds checks unless it decodes a value type.
// Conversely, bounds checks have to be performed before the decoding function
@ -1104,7 +1103,7 @@ string ABIFunctions::abiDecodingFunction(Type const& _type, bool _fromMemory, bo
return abiDecodingFunctionValueType(_type, _fromMemory);
}
string ABIFunctions::abiDecodingFunctionValueType(Type const& _type, bool _fromMemory)
std::string ABIFunctions::abiDecodingFunctionValueType(Type const& _type, bool _fromMemory)
{
Type const* decodingType = _type.decodingType();
solAssert(decodingType, "");
@ -1113,7 +1112,7 @@ string ABIFunctions::abiDecodingFunctionValueType(Type const& _type, bool _fromM
solAssert(!decodingType->isDynamicallyEncoded(), "");
solAssert(decodingType->calldataEncodedSize() == 32, "");
string functionName =
std::string functionName =
"abi_decode_" +
_type.identifier() +
(_fromMemory ? "_fromMemory" : "");
@ -1134,17 +1133,17 @@ string ABIFunctions::abiDecodingFunctionValueType(Type const& _type, bool _fromM
}
string ABIFunctions::abiDecodingFunctionArray(ArrayType const& _type, bool _fromMemory)
std::string ABIFunctions::abiDecodingFunctionArray(ArrayType const& _type, bool _fromMemory)
{
solAssert(_type.dataStoredIn(DataLocation::Memory), "");
string functionName =
std::string functionName =
"abi_decode_" +
_type.identifier() +
(_fromMemory ? "_fromMemory" : "");
return createFunction(functionName, [&]() {
string load = _fromMemory ? "mload" : "calldataload";
std::string load = _fromMemory ? "mload" : "calldataload";
Whiskers templ(
R"(
// <readableTypeName>
@ -1166,14 +1165,14 @@ string ABIFunctions::abiDecodingFunctionArray(ArrayType const& _type, bool _from
});
}
string ABIFunctions::abiDecodingFunctionArrayAvailableLength(ArrayType const& _type, bool _fromMemory)
std::string ABIFunctions::abiDecodingFunctionArrayAvailableLength(ArrayType const& _type, bool _fromMemory)
{
solAssert(_type.dataStoredIn(DataLocation::Memory), "");
if (_type.isByteArrayOrString())
return abiDecodingFunctionByteArrayAvailableLength(_type, _fromMemory);
solAssert(_type.calldataStride() > 0, "");
string functionName =
std::string functionName =
"abi_decode_available_length_" +
_type.identifier() +
(_fromMemory ? "_fromMemory" : "");
@ -1224,7 +1223,7 @@ string ABIFunctions::abiDecodingFunctionArrayAvailableLength(ArrayType const& _t
});
}
string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type)
std::string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type)
{
solAssert(_type.dataStoredIn(DataLocation::CallData), "");
if (!_type.isDynamicallySized())
@ -1232,7 +1231,7 @@ string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type)
solAssert(_type.calldataStride() > 0, "");
solAssert(_type.calldataStride() < u256("0xffffffffffffffff"), "");
string functionName =
std::string functionName =
"abi_decode_" +
_type.identifier();
return createFunction(functionName, [&]() {
@ -1273,12 +1272,12 @@ string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type)
});
}
string ABIFunctions::abiDecodingFunctionByteArrayAvailableLength(ArrayType const& _type, bool _fromMemory)
std::string ABIFunctions::abiDecodingFunctionByteArrayAvailableLength(ArrayType const& _type, bool _fromMemory)
{
solAssert(_type.dataStoredIn(DataLocation::Memory), "");
solAssert(_type.isByteArrayOrString(), "");
string functionName =
std::string functionName =
"abi_decode_available_length_" +
_type.identifier() +
(_fromMemory ? "_fromMemory" : "");
@ -1302,10 +1301,10 @@ string ABIFunctions::abiDecodingFunctionByteArrayAvailableLength(ArrayType const
});
}
string ABIFunctions::abiDecodingFunctionCalldataStruct(StructType const& _type)
std::string ABIFunctions::abiDecodingFunctionCalldataStruct(StructType const& _type)
{
solAssert(_type.dataStoredIn(DataLocation::CallData), "");
string functionName =
std::string functionName =
"abi_decode_" +
_type.identifier();
@ -1321,15 +1320,15 @@ string ABIFunctions::abiDecodingFunctionCalldataStruct(StructType const& _type)
w("revertString", revertReasonIfDebugFunction("ABI decoding: struct calldata too short"));
w("functionName", functionName);
w("readableTypeName", _type.toString(true));
w("minimumSize", to_string(_type.isDynamicallyEncoded() ? _type.calldataEncodedTailSize() : _type.calldataEncodedSize(true)));
w("minimumSize", std::to_string(_type.isDynamicallyEncoded() ? _type.calldataEncodedTailSize() : _type.calldataEncodedSize(true)));
return w.render();
});
}
string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fromMemory)
std::string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fromMemory)
{
solAssert(!_type.dataStoredIn(DataLocation::CallData), "");
string functionName =
std::string functionName =
"abi_decode_" +
_type.identifier() +
(_fromMemory ? "_fromMemory" : "");
@ -1356,7 +1355,7 @@ string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fr
solAssert(_type.memoryDataSize() < u256("0xffffffffffffffff"), "");
templ("memorySize", toCompactHexWithPrefix(_type.memoryDataSize()));
size_t headPos = 0;
vector<map<string, string>> members;
std::vector<std::map<std::string, std::string>> members;
for (auto const& member: _type.members(nullptr))
{
solAssert(member.type, "");
@ -1376,7 +1375,7 @@ string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fr
// TODO add test
memberTempl("revertString", revertReasonIfDebugFunction("ABI decoding: invalid struct offset"));
memberTempl("load", _fromMemory ? "mload" : "calldataload");
memberTempl("pos", to_string(headPos));
memberTempl("pos", std::to_string(headPos));
memberTempl("memoryOffset", toCompactHexWithPrefix(_type.memoryOffsetOfMember(member.name)));
memberTempl("abiDecode", abiDecodingFunction(*member.type, _fromMemory, false));
@ -1391,11 +1390,11 @@ string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fr
});
}
string ABIFunctions::abiDecodingFunctionFunctionType(FunctionType const& _type, bool _fromMemory, bool _forUseOnStack)
std::string ABIFunctions::abiDecodingFunctionFunctionType(FunctionType const& _type, bool _fromMemory, bool _forUseOnStack)
{
solAssert(_type.kind() == FunctionType::Kind::External, "");
string functionName =
std::string functionName =
"abi_decode_" +
_type.identifier() +
(_fromMemory ? "_fromMemory" : "") +
@ -1430,10 +1429,10 @@ string ABIFunctions::abiDecodingFunctionFunctionType(FunctionType const& _type,
});
}
string ABIFunctions::calldataAccessFunction(Type const& _type)
std::string ABIFunctions::calldataAccessFunction(Type const& _type)
{
solAssert(_type.isValueType() || _type.dataStoredIn(DataLocation::CallData), "");
string functionName = "calldata_access_" + _type.identifier();
std::string functionName = "calldata_access_" + _type.identifier();
return createFunction(functionName, [&]() {
if (_type.isDynamicallyEncoded())
{
@ -1477,7 +1476,7 @@ string ABIFunctions::calldataAccessFunction(Type const& _type)
}
else if (_type.isValueType())
{
string decodingFunction;
std::string decodingFunction;
if (auto const* functionType = dynamic_cast<FunctionType const*>(&_type))
decodingFunction = abiDecodingFunctionFunctionType(*functionType, false, false);
else
@ -1510,9 +1509,9 @@ string ABIFunctions::calldataAccessFunction(Type const& _type)
});
}
string ABIFunctions::arrayStoreLengthForEncodingFunction(ArrayType const& _type, EncodingOptions const& _options)
std::string ABIFunctions::arrayStoreLengthForEncodingFunction(ArrayType const& _type, EncodingOptions const& _options)
{
string functionName = "array_storeLengthForEncoding_" + _type.identifier() + _options.toFunctionNameSuffix();
std::string functionName = "array_storeLengthForEncoding_" + _type.identifier() + _options.toFunctionNameSuffix();
return createFunction(functionName, [&]() {
if (_type.isDynamicallySized() && !_options.dynamicInplace)
return Whiskers(R"(
@ -1534,7 +1533,7 @@ string ABIFunctions::arrayStoreLengthForEncodingFunction(ArrayType const& _type,
});
}
string ABIFunctions::createFunction(string const& _name, function<string ()> const& _creator)
std::string ABIFunctions::createFunction(std::string const& _name, std::function<std::string ()> const& _creator)
{
return m_functionCollector.createFunction(_name, _creator);
}

View File

@ -36,7 +36,6 @@
#include <libevmasm/Instruction.h>
#include <liblangutil/Exceptions.h>
using namespace std;
using namespace solidity;
using namespace solidity::evmasm;
using namespace solidity::frontend;
@ -314,7 +313,7 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord
if (!_sourceType.isByteArrayOrString())
convertLengthToSize(_sourceType);
string routine = "calldatacopy(target, source, len)\n";
std::string routine = "calldatacopy(target, source, len)\n";
if (_padToWordBoundaries)
routine += R"(
// Set padding suffix to zero
@ -890,7 +889,7 @@ void ArrayUtils::popStorageArrayElement(ArrayType const& _type) const
sstore(ref, slot_value)
})");
code("panicSelector", util::selectorFromSignatureU256("Panic(uint256)").str());
code("emptyArrayPop", to_string(unsigned(util::PanicCode::EmptyArrayPop)));
code("emptyArrayPop", std::to_string(unsigned(util::PanicCode::EmptyArrayPop)));
m_context.appendInlineAssembly(code.render(), {"ref", "slot_value", "length"});
m_context << Instruction::POP << Instruction::POP << Instruction::POP;
}

View File

@ -26,13 +26,12 @@
#include <libsolidity/codegen/ContractCompiler.h>
#include <libevmasm/Assembly.h>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
void Compiler::compileContract(
ContractDefinition const& _contract,
std::map<ContractDefinition const*, shared_ptr<Compiler const>> const& _otherCompilers,
std::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers,
bytes const& _metadata
)
{

View File

@ -55,7 +55,6 @@
#undef SOL_OUTPUT_ASM
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::evmasm;
@ -68,7 +67,7 @@ void CompilerContext::addStateVariable(
unsigned _byteOffset
)
{
m_stateVariables[&_declaration] = make_pair(_storageOffset, _byteOffset);
m_stateVariables[&_declaration] = std::make_pair(_storageOffset, _byteOffset);
}
void CompilerContext::addImmutable(VariableDeclaration const& _variable)
@ -88,14 +87,14 @@ size_t CompilerContext::immutableMemoryOffset(VariableDeclaration const& _variab
return m_immutableVariables.at(&_variable);
}
vector<string> CompilerContext::immutableVariableSlotNames(VariableDeclaration const& _variable)
std::vector<std::string> CompilerContext::immutableVariableSlotNames(VariableDeclaration const& _variable)
{
string baseName = to_string(_variable.id());
std::string baseName = std::to_string(_variable.id());
solAssert(_variable.annotation().type->sizeOnStack() > 0, "");
if (_variable.annotation().type->sizeOnStack() == 1)
return {baseName};
vector<string> names;
auto collectSlotNames = [&](string const& _baseName, Type const* type, auto const& _recurse) -> void {
std::vector<std::string> names;
auto collectSlotNames = [&](std::string const& _baseName, Type const* type, auto const& _recurse) -> void {
for (auto const& [slot, type]: type->stackItems())
if (type)
_recurse(_baseName + " " + slot, type, _recurse);
@ -121,10 +120,10 @@ void CompilerContext::startFunction(Declaration const& _function)
}
void CompilerContext::callLowLevelFunction(
string const& _name,
std::string const& _name,
unsigned _inArgs,
unsigned _outArgs,
function<void(CompilerContext&)> const& _generator
std::function<void(CompilerContext&)> const& _generator
)
{
evmasm::AssemblyItem retTag = pushNewTag();
@ -138,7 +137,7 @@ void CompilerContext::callLowLevelFunction(
}
void CompilerContext::callYulFunction(
string const& _name,
std::string const& _name,
unsigned _inArgs,
unsigned _outArgs
)
@ -152,10 +151,10 @@ void CompilerContext::callYulFunction(
}
evmasm::AssemblyItem CompilerContext::lowLevelFunctionTag(
string const& _name,
std::string const& _name,
unsigned _inArgs,
unsigned _outArgs,
function<void(CompilerContext&)> const& _generator
std::function<void(CompilerContext&)> const& _generator
)
{
auto it = m_lowLevelFunctions.find(_name);
@ -174,10 +173,10 @@ void CompilerContext::appendMissingLowLevelFunctions()
{
while (!m_lowLevelFunctionGenerationQueue.empty())
{
string name;
std::string name;
unsigned inArgs;
unsigned outArgs;
function<void(CompilerContext&)> generator;
std::function<void(CompilerContext&)> generator;
tie(name, inArgs, outArgs, generator) = m_lowLevelFunctionGenerationQueue.front();
m_lowLevelFunctionGenerationQueue.pop();
@ -195,7 +194,7 @@ void CompilerContext::appendYulUtilityFunctions(OptimiserSettings const& _optimi
solAssert(!m_appendYulUtilityFunctionsRan, "requestedYulFunctions called more than once.");
m_appendYulUtilityFunctionsRan = true;
string code = m_yulFunctionCollector.requestedFunctions();
std::string code = m_yulFunctionCollector.requestedFunctions();
if (!code.empty())
{
appendInlineAssembly(
@ -233,7 +232,7 @@ void CompilerContext::removeVariable(Declaration const& _declaration)
void CompilerContext::removeVariablesAboveStackHeight(unsigned _stackHeight)
{
vector<Declaration const*> toRemove;
std::vector<Declaration const*> toRemove;
for (auto _var: m_localVariables)
{
solAssert(!_var.second.empty(), "");
@ -250,14 +249,14 @@ unsigned CompilerContext::numberOfLocalVariables() const
return static_cast<unsigned>(m_localVariables.size());
}
shared_ptr<evmasm::Assembly> CompilerContext::compiledContract(ContractDefinition const& _contract) const
std::shared_ptr<evmasm::Assembly> CompilerContext::compiledContract(ContractDefinition const& _contract) const
{
auto ret = m_otherCompilers.find(&_contract);
solAssert(ret != m_otherCompilers.end(), "Compiled contract not found.");
return ret->second->assemblyPtr();
}
shared_ptr<evmasm::Assembly> CompilerContext::compiledContractRuntime(ContractDefinition const& _contract) const
std::shared_ptr<evmasm::Assembly> CompilerContext::compiledContractRuntime(ContractDefinition const& _contract) const
{
auto ret = m_otherCompilers.find(&_contract);
solAssert(ret != m_otherCompilers.end(), "Compiled contract not found.");
@ -320,7 +319,7 @@ unsigned CompilerContext::currentToBaseStackOffset(unsigned _offset) const
return static_cast<unsigned>(m_asm->deposit()) - _offset - 1;
}
pair<u256, unsigned> CompilerContext::storageLocationOfVariable(Declaration const& _declaration) const
std::pair<u256, unsigned> CompilerContext::storageLocationOfVariable(Declaration const& _declaration) const
{
auto it = m_stateVariables.find(&_declaration);
solAssert(it != m_stateVariables.end(), "Variable not found in storage.");
@ -349,13 +348,13 @@ CompilerContext& CompilerContext::appendConditionalPanic(util::PanicCode _code)
return *this;
}
CompilerContext& CompilerContext::appendRevert(string const& _message)
CompilerContext& CompilerContext::appendRevert(std::string const& _message)
{
appendInlineAssembly("{ " + revertReasonIfDebug(_message) + " }");
return *this;
}
CompilerContext& CompilerContext::appendConditionalRevert(bool _forwardReturnData, string const& _message)
CompilerContext& CompilerContext::appendConditionalRevert(bool _forwardReturnData, std::string const& _message)
{
if (_forwardReturnData && m_evmVersion.supportsReturndata())
appendInlineAssembly(R"({
@ -372,24 +371,24 @@ CompilerContext& CompilerContext::appendConditionalRevert(bool _forwardReturnDat
void CompilerContext::resetVisitedNodes(ASTNode const* _node)
{
stack<ASTNode const*> newStack;
std::stack<ASTNode const*> newStack;
newStack.push(_node);
std::swap(m_visitedNodes, newStack);
updateSourceLocation();
}
void CompilerContext::appendInlineAssembly(
string const& _assembly,
vector<string> const& _localVariables,
set<string> const& _externallyUsedFunctions,
std::string const& _assembly,
std::vector<std::string> const& _localVariables,
std::set<std::string> const& _externallyUsedFunctions,
bool _system,
OptimiserSettings const& _optimiserSettings,
string _sourceName
std::string _sourceName
)
{
unsigned startStackHeight = stackHeight();
set<yul::YulString> externallyUsedIdentifiers;
std::set<yul::YulString> externallyUsedIdentifiers;
for (auto const& fun: _externallyUsedFunctions)
externallyUsedIdentifiers.insert(yul::YulString(fun));
for (auto const& var: _localVariables)
@ -438,19 +437,19 @@ void CompilerContext::appendInlineAssembly(
ErrorReporter errorReporter(errors);
langutil::CharStream charStream(_assembly, _sourceName);
yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion);
optional<langutil::SourceLocation> locationOverride;
std::optional<langutil::SourceLocation> locationOverride;
if (!_system)
locationOverride = m_asm->currentSourceLocation();
shared_ptr<yul::Block> parserResult =
std::shared_ptr<yul::Block> parserResult =
yul::Parser(errorReporter, dialect, std::move(locationOverride))
.parse(charStream);
#ifdef SOL_OUTPUT_ASM
cout << yul::AsmPrinter(&dialect)(*parserResult) << endl;
#endif
auto reportError = [&](string const& _context)
auto reportError = [&](std::string const& _context)
{
string message =
std::string message =
"Error parsing/analyzing inline assembly block:\n" +
_context + "\n"
"------------------ Input: -----------------\n" +
@ -483,7 +482,7 @@ void CompilerContext::appendInlineAssembly(
{
yul::Object obj;
obj.code = parserResult;
obj.analysisInfo = make_shared<yul::AsmAnalysisInfo>(analysisInfo);
obj.analysisInfo = std::make_shared<yul::AsmAnalysisInfo>(analysisInfo);
solAssert(!dialect.providesObjectAccess());
optimizeYul(obj, dialect, _optimiserSettings, externallyUsedIdentifiers);
@ -493,7 +492,7 @@ void CompilerContext::appendInlineAssembly(
// Store as generated sources, but first re-parse to update the source references.
solAssert(m_generatedYulUtilityCode.empty(), "");
m_generatedYulUtilityCode = yul::AsmPrinter(dialect)(*obj.code);
string code = yul::AsmPrinter{dialect}(*obj.code);
std::string code = yul::AsmPrinter{dialect}(*obj.code);
langutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName);
obj.code = yul::Parser(errorReporter, dialect).parse(charStream);
*obj.analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj);
@ -548,7 +547,7 @@ void CompilerContext::optimizeYul(yul::Object& _object, yul::EVMDialect const& _
_optimiserSettings.optimizeStackAllocation,
_optimiserSettings.yulOptimiserSteps,
_optimiserSettings.yulOptimiserCleanupSteps,
isCreation? nullopt : make_optional(_optimiserSettings.expectedExecutionsPerDeployment),
isCreation? std::nullopt : std::make_optional(_optimiserSettings.expectedExecutionsPerDeployment),
_externalIdentifiers
);
@ -558,11 +557,11 @@ void CompilerContext::optimizeYul(yul::Object& _object, yul::EVMDialect const& _
#endif
}
string CompilerContext::revertReasonIfDebug(string const& _message)
std::string CompilerContext::revertReasonIfDebug(std::string const& _message)
{
return YulUtilFunctions::revertReasonIfDebugBody(
m_revertStrings,
"mload(" + to_string(CompilerUtils::freeMemoryPointer) + ")",
"mload(" + std::to_string(CompilerUtils::freeMemoryPointer) + ")",
_message
);
}
@ -590,14 +589,14 @@ evmasm::AssemblyItem CompilerContext::FunctionCompilationQueue::entryLabel(
}
// some name that cannot clash with yul function names.
string labelName = "@" + _declaration.name() + "_" + to_string(_declaration.id());
std::string labelName = "@" + _declaration.name() + "_" + std::to_string(_declaration.id());
evmasm::AssemblyItem tag = _context.namedTag(
labelName,
params,
returns,
_declaration.id()
);
m_entryLabels.insert(make_pair(&_declaration, tag));
m_entryLabels.insert(std::make_pair(&_declaration, tag));
m_functionsToCompile.push(&_declaration);
return tag.tag();
}

View File

@ -33,7 +33,6 @@
#include <libsolutil/Whiskers.h>
#include <libsolutil/StackTooDeepString.h>
using namespace std;
using namespace solidity;
using namespace solidity::evmasm;
using namespace solidity::frontend;
@ -105,9 +104,9 @@ void CompilerUtils::revertWithStringData(Type const& _argumentType)
}
void CompilerUtils::revertWithError(
string const& _signature,
vector<Type const*> const& _parameterTypes,
vector<Type const*> const& _argumentTypes
std::string const& _signature,
std::vector<Type const*> const& _parameterTypes,
std::vector<Type const*> const& _argumentTypes
)
{
fetchFreeMemoryPointer();
@ -215,7 +214,7 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound
m_context << Instruction::DUP1;
storeStringData(bytesConstRef(str->value()));
if (_padToWordBoundaries)
m_context << u256(max<size_t>(32, ((str->value().size() + 31) / 32) * 32));
m_context << u256(std::max<size_t>(32, ((str->value().size() + 31) / 32) * 32));
else
m_context << u256(str->value().size());
m_context << Instruction::ADD;
@ -264,7 +263,7 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem
Whiskers templ(R"({
if lt(len, <encodedSize>) { <revertString> }
})");
templ("encodedSize", to_string(encodedSize));
templ("encodedSize", std::to_string(encodedSize));
templ("revertString", m_context.revertReasonIfDebug("Calldata too short"));
m_context.appendInlineAssembly(templ.render(), {"len"});
@ -320,7 +319,7 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem
mstore(dst, array_length)
dst := add(dst, 0x20)
})");
templ("item_size", to_string(arrayType.calldataStride()));
templ("item_size", std::to_string(arrayType.calldataStride()));
// TODO add test
templ("revertStringPointer", m_context.revertReasonIfDebug("ABI memory decoding: invalid data pointer"));
templ("revertStringStart", m_context.revertReasonIfDebug("ABI memory decoding: invalid data start"));
@ -374,7 +373,7 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem
m_context.appendInlineAssembly(Whiskers(R"({
if or(
gt(array_length, 0x100000000),
gt(add(data_ptr, mul(array_length, )" + to_string(arrayType.calldataStride()) + R"()), input_end)
gt(add(data_ptr, mul(array_length, )" + std::to_string(arrayType.calldataStride()) + R"()), input_end)
) { <revertString> }
})")
("revertString", m_context.revertReasonIfDebug("ABI calldata decoding: invalid data pointer"))
@ -618,7 +617,7 @@ void CompilerUtils::abiEncodeV2(
// stack: <$value0> <$value1> ... <$value(n-1)> <$headStart>
string encoderName =
std::string encoderName =
_padToWordBoundaries ?
m_context.abiFunctions().tupleEncoderReversed(_givenTypes, _targetTypes, _encodeAsLibraryTypes) :
m_context.abiFunctions().tupleEncoderPackedReversed(_givenTypes, _targetTypes);
@ -631,7 +630,7 @@ void CompilerUtils::abiDecodeV2(TypePointers const& _parameterTypes, bool _fromM
m_context << Instruction::DUP2 << Instruction::ADD;
m_context << Instruction::SWAP1;
// stack: <end> <start>
string decoderName = m_context.abiFunctions().tupleDecoder(_parameterTypes, _fromMemory);
std::string decoderName = m_context.abiFunctions().tupleDecoder(_parameterTypes, _fromMemory);
m_context.callYulFunction(decoderName, 2, sizeOnStack(_parameterTypes));
}
@ -646,7 +645,7 @@ void CompilerUtils::zeroInitialiseMemoryArray(ArrayType const& _type)
calldatacopy(memptr, calldatasize(), size)
memptr := add(memptr, size)
})");
templ("element_size", to_string(_type.memoryStride()));
templ("element_size", std::to_string(_type.memoryStride()));
m_context.appendInlineAssembly(templ.render(), {"length", "memptr"});
}
else
@ -842,7 +841,7 @@ void CompilerUtils::convertType(
m_context << Instruction::POP << u256(0);
else if (targetType.numBytes() > typeOnStack.numBytes() || _cleanupNeeded)
{
unsigned bytes = min(typeOnStack.numBytes(), targetType.numBytes());
unsigned bytes = std::min(typeOnStack.numBytes(), targetType.numBytes());
m_context << ((u256(1) << (256 - bytes * 8)) - 1);
m_context << Instruction::NOT << Instruction::AND;
}
@ -960,7 +959,7 @@ void CompilerUtils::convertType(
case Type::Category::StringLiteral:
{
auto const& literalType = dynamic_cast<StringLiteralType const&>(_typeOnStack);
string const& value = literalType.value();
std::string const& value = literalType.value();
bytesConstRef data(value);
if (targetTypeCategory == Type::Category::FixedBytes)
{
@ -1186,7 +1185,7 @@ void CompilerUtils::convertType(
for (auto const& member: typeOnStack->members(nullptr))
{
solAssert(!member.type->containsNestedMapping());
pair<u256, unsigned> const& offsets = typeOnStack->storageOffsetsOfMember(member.name);
std::pair<u256, unsigned> const& offsets = typeOnStack->storageOffsetsOfMember(member.name);
_context << offsets.first << Instruction::DUP3 << Instruction::ADD;
_context << u256(offsets.second);
StorageItem(_context, *member.type).retrieveValue(SourceLocation(), true);
@ -1268,7 +1267,7 @@ void CompilerUtils::convertType(
if (sourceSize > 0 || targetSize > 0)
{
// Move it back into its place.
for (unsigned j = 0; j < min(sourceSize, targetSize); ++j)
for (unsigned j = 0; j < std::min(sourceSize, targetSize); ++j)
m_context <<
swapInstruction(depth + targetSize - sourceSize) <<
Instruction::POP;
@ -1375,7 +1374,7 @@ void CompilerUtils::pushZeroValue(Type const& _type)
[type](CompilerContext& _context) {
CompilerUtils utils(_context);
utils.allocateMemory(max<u256>(32u, type->memoryDataSize()));
utils.allocateMemory(std::max<u256>(32u, type->memoryDataSize()));
_context << Instruction::DUP1;
if (auto structType = dynamic_cast<StructType const*>(type))
@ -1493,7 +1492,7 @@ void CompilerUtils::popAndJump(unsigned _toHeight, evmasm::AssemblyItem const& _
m_context.adjustStackOffset(static_cast<int>(amount));
}
unsigned CompilerUtils::sizeOnStack(vector<Type const*> const& _variableTypes)
unsigned CompilerUtils::sizeOnStack(std::vector<Type const*> const& _variableTypes)
{
unsigned size = 0;
for (Type const* type: _variableTypes)
@ -1509,7 +1508,7 @@ void CompilerUtils::computeHashStatic()
void CompilerUtils::copyContractCodeToMemory(ContractDefinition const& contract, bool _creation)
{
string which = _creation ? "Creation" : "Runtime";
std::string which = _creation ? "Creation" : "Runtime";
m_context.callLowLevelFunction(
"$copyContract" + which + "CodeToMemory_" + contract.type()->identifier(),
1,
@ -1517,7 +1516,7 @@ void CompilerUtils::copyContractCodeToMemory(ContractDefinition const& contract,
[&contract, _creation](CompilerContext& _context)
{
// copy the contract's code into memory
shared_ptr<evmasm::Assembly> assembly =
std::shared_ptr<evmasm::Assembly> assembly =
_creation ?
_context.compiledContract(contract) :
_context.compiledContractRuntime(contract);

View File

@ -55,7 +55,6 @@
#include <algorithm>
#include <limits>
using namespace std;
using namespace solidity;
using namespace solidity::evmasm;
using namespace solidity::frontend;
@ -80,7 +79,7 @@ public:
{
solAssert(
m_context.stackHeight() == stackHeight,
std::string("I sense a disturbance in the stack: ") + to_string(m_context.stackHeight()) + " vs " + to_string(stackHeight)
std::string("I sense a disturbance in the stack: ") + std::to_string(m_context.stackHeight()) + " vs " + std::to_string(stackHeight)
);
}
private:
@ -92,7 +91,7 @@ private:
void ContractCompiler::compileContract(
ContractDefinition const& _contract,
map<ContractDefinition const*, shared_ptr<Compiler const>> const& _otherCompilers
std::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers
)
{
CompilerContext::LocationSetter locationSetter(m_context, _contract);
@ -111,7 +110,7 @@ void ContractCompiler::compileContract(
size_t ContractCompiler::compileConstructor(
ContractDefinition const& _contract,
std::map<ContractDefinition const*, shared_ptr<Compiler const>> const& _otherCompilers
std::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers
)
{
CompilerContext::LocationSetter locationSetter(m_context, _contract);
@ -126,7 +125,7 @@ size_t ContractCompiler::compileConstructor(
void ContractCompiler::initializeContext(
ContractDefinition const& _contract,
map<ContractDefinition const*, shared_ptr<Compiler const>> const& _otherCompilers
std::map<ContractDefinition const*, std::shared_ptr<Compiler const>> const& _otherCompilers
)
{
m_context.setUseABICoderV2(*_contract.sourceUnit().annotation().useABICoderV2);
@ -187,7 +186,7 @@ size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _cont
CompilerContext::LocationSetter locationSetter(m_context, _contract);
m_context << deployRoutine;
solAssert(m_context.runtimeSub() != numeric_limits<size_t>::max(), "Runtime sub not registered");
solAssert(m_context.runtimeSub() != std::numeric_limits<size_t>::max(), "Runtime sub not registered");
ContractType contractType(_contract);
auto const& immutables = contractType.immutableVariables();
@ -231,7 +230,7 @@ size_t ContractCompiler::deployLibrary(ContractDefinition const& _contract)
CompilerContext::LocationSetter locationSetter(m_context, _contract);
solAssert(m_context.runtimeSub() != numeric_limits<size_t>::max(), "Runtime sub not registered");
solAssert(m_context.runtimeSub() != std::numeric_limits<size_t>::max(), "Runtime sub not registered");
m_context.pushSubroutineSize(m_context.runtimeSub());
m_context.pushSubroutineOffset(m_context.runtimeSub());
// This code replaces the address added by appendDeployTimeAddress().
@ -324,8 +323,8 @@ void ContractCompiler::appendDelegatecallCheck()
}
void ContractCompiler::appendInternalSelector(
map<FixedHash<4>, evmasm::AssemblyItem const> const& _entryPoints,
vector<FixedHash<4>> const& _ids,
std::map<FixedHash<4>, evmasm::AssemblyItem const> const& _entryPoints,
std::vector<FixedHash<4>> const& _ids,
evmasm::AssemblyItem const& _notFoundTag,
size_t _runs
)
@ -369,11 +368,11 @@ void ContractCompiler::appendInternalSelector(
m_context << dupInstruction(1) << u256(FixedHash<4>::Arith(pivot)) << Instruction::GT;
evmasm::AssemblyItem lessTag{m_context.appendConditionalJump()};
// Here, we have funid >= pivot
vector<FixedHash<4>> larger{_ids.begin() + static_cast<ptrdiff_t>(pivotIndex), _ids.end()};
std::vector<FixedHash<4>> larger{_ids.begin() + static_cast<ptrdiff_t>(pivotIndex), _ids.end()};
appendInternalSelector(_entryPoints, larger, _notFoundTag, _runs);
m_context << lessTag;
// Here, we have funid < pivot
vector<FixedHash<4>> smaller{_ids.begin(), _ids.begin() + static_cast<ptrdiff_t>(pivotIndex)};
std::vector<FixedHash<4>> smaller{_ids.begin(), _ids.begin() + static_cast<ptrdiff_t>(pivotIndex)};
appendInternalSelector(_entryPoints, smaller, _notFoundTag, _runs);
}
else
@ -411,8 +410,8 @@ bool hasPayableFunctions(ContractDefinition const& _contract)
void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contract)
{
map<FixedHash<4>, FunctionTypePointer> interfaceFunctions = _contract.interfaceFunctions();
map<FixedHash<4>, evmasm::AssemblyItem const> callDataUnpackerEntryPoints;
std::map<FixedHash<4>, FunctionTypePointer> interfaceFunctions = _contract.interfaceFunctions();
std::map<FixedHash<4>, evmasm::AssemblyItem const> callDataUnpackerEntryPoints;
if (_contract.isLibrary())
{
@ -448,7 +447,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac
CompilerUtils(m_context).loadFromMemory(0, IntegerType(CompilerUtils::dataStartOffset * 8), true, false);
// stack now is: <can-call-non-view-functions>? <funhash>
vector<FixedHash<4>> sortedIDs;
std::vector<FixedHash<4>> sortedIDs;
for (auto const& it: interfaceFunctions)
{
callDataUnpackerEntryPoints.emplace(it.first, m_context.newTag());
@ -572,7 +571,7 @@ void ContractCompiler::appendReturnValuePacker(TypePointers const& _typeParamete
void ContractCompiler::registerStateVariables(ContractDefinition const& _contract)
{
for (auto const& var: ContractType(_contract).stateVariables())
m_context.addStateVariable(*get<0>(var), get<1>(var), get<2>(var));
m_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var));
}
void ContractCompiler::registerImmutableVariables(ContractDefinition const& _contract)
@ -645,7 +644,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function)
m_breakTags.clear();
m_continueTags.clear();
m_currentFunction = &_function;
m_modifierDepth = numeric_limits<unsigned>::max();
m_modifierDepth = std::numeric_limits<unsigned>::max();
m_scopeStackHeight.clear();
m_context.setModifierDepth(0);
@ -662,10 +661,10 @@ bool ContractCompiler::visit(FunctionDefinition const& _function)
unsigned const c_argumentsSize = CompilerUtils::sizeOnStack(_function.parameters());
unsigned const c_returnValuesSize = CompilerUtils::sizeOnStack(_function.returnParameters());
vector<int> stackLayout;
std::vector<int> stackLayout;
if (!_function.isConstructor() && !_function.isFallback())
stackLayout.push_back(static_cast<int>(c_returnValuesSize)); // target of return address
stackLayout += vector<int>(c_argumentsSize, -1); // discard all arguments
stackLayout += std::vector<int>(c_argumentsSize, -1); // discard all arguments
for (size_t i = 0; i < c_returnValuesSize; ++i)
stackLayout.push_back(static_cast<int>(i));
@ -684,7 +683,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function)
else
{
m_context << swapInstruction(static_cast<unsigned>(stackLayout.size()) - static_cast<unsigned>(stackLayout.back()) - 1u);
swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back());
std::swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back());
}
for (size_t i = 0; i < stackLayout.size(); ++i)
if (stackLayout[i] != static_cast<int>(i))
@ -790,7 +789,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
unsigned stackDiff = static_cast<unsigned>(_assembly.stackHeight()) - m_context.baseStackOffsetOfVariable(*variable);
if (!ref->second.suffix.empty())
{
string const& suffix = ref->second.suffix;
std::string const& suffix = ref->second.suffix;
if (variable->type()->dataStoredIn(DataLocation::Storage))
{
solAssert(suffix == "offset" || suffix == "slot", "");
@ -865,7 +864,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
// lvalue context
auto variable = dynamic_cast<VariableDeclaration const*>(decl);
unsigned stackDiff = static_cast<unsigned>(_assembly.stackHeight()) - m_context.baseStackOffsetOfVariable(*variable) - 1;
string const& suffix = ref->second.suffix;
std::string const& suffix = ref->second.suffix;
if (variable->type()->dataStoredIn(DataLocation::Storage))
{
solAssert(
@ -928,7 +927,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
yul::AsmAnalysisInfo* analysisInfo = _inlineAssembly.annotation().analysisInfo.get();
// Only used in the scope below, but required to live outside to keep the
// shared_ptr's alive
// std::shared_ptr's alive
yul::Object object = {};
// The optimiser cannot handle external references
@ -941,8 +940,8 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
solAssert(dialect, "");
// Create a modifiable copy of the code and analysis
object.code = make_shared<yul::Block>(yul::ASTCopier().translate(*code));
object.analysisInfo = make_shared<yul::AsmAnalysisInfo>(yul::AsmAnalyzer::analyzeStrictAssertCorrect(*dialect, object));
object.code = std::make_shared<yul::Block>(yul::ASTCopier().translate(*code));
object.analysisInfo = std::make_shared<yul::AsmAnalysisInfo>(yul::AsmAnalyzer::analyzeStrictAssertCorrect(*dialect, object));
m_context.optimizeYul(object, *dialect, m_optimiserSettings);
@ -989,10 +988,10 @@ bool ContractCompiler::visit(TryStatement const& _tryStatement)
TryCatchClause const& successClause = *_tryStatement.clauses().front();
if (successClause.parameters())
{
vector<Type const*> exprTypes{_tryStatement.externalCall().annotation().type};
std::vector<Type const*> exprTypes{_tryStatement.externalCall().annotation().type};
if (auto tupleType = dynamic_cast<TupleType const*>(exprTypes.front()))
exprTypes = tupleType->components();
vector<ASTPointer<VariableDeclaration>> const& params = successClause.parameters()->parameters();
std::vector<ASTPointer<VariableDeclaration>> const& params = successClause.parameters()->parameters();
solAssert(exprTypes.size() == params.size(), "");
for (size_t i = 0; i < exprTypes.size(); ++i)
solAssert(params[i] && exprTypes[i] && *params[i]->annotation().type == *exprTypes[i], "");
@ -1008,7 +1007,7 @@ bool ContractCompiler::visit(TryStatement const& _tryStatement)
return false;
}
void ContractCompiler::handleCatch(vector<ASTPointer<TryCatchClause>> const& _catchClauses)
void ContractCompiler::handleCatch(std::vector<ASTPointer<TryCatchClause>> const& _catchClauses)
{
// Stack is empty.
ASTPointer<TryCatchClause> error{};
@ -1285,7 +1284,7 @@ bool ContractCompiler::visit(Return const& _return)
if (Expression const* expression = _return.expression())
{
solAssert(_return.annotation().functionReturnParameters, "Invalid return parameters pointer.");
vector<ASTPointer<VariableDeclaration>> const& returnParameters =
std::vector<ASTPointer<VariableDeclaration>> const& returnParameters =
_return.annotation().functionReturnParameters->parameters();
TypePointers types;
for (auto const& retVariable: returnParameters)
@ -1432,7 +1431,7 @@ void ContractCompiler::appendModifierOrFunctionCode()
solAssert(m_currentFunction, "");
unsigned stackSurplus = 0;
Block const* codeBlock = nullptr;
vector<VariableDeclaration const*> addedVariables;
std::vector<VariableDeclaration const*> addedVariables;
m_modifierDepth++;
m_context.setModifierDepth(m_modifierDepth);

View File

@ -43,7 +43,6 @@
#include <numeric>
#include <utility>
using namespace std;
using namespace solidity;
using namespace solidity::evmasm;
using namespace solidity::frontend;
@ -242,7 +241,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
if (auto arrayType = dynamic_cast<ArrayType const*>(returnTypes[i]))
if (!arrayType->isByteArrayOrString())
continue;
pair<u256, unsigned> const& offsets = structType->storageOffsetsOfMember(names[i]);
std::pair<u256, unsigned> const& offsets = structType->storageOffsetsOfMember(names[i]);
m_context << Instruction::DUP1 << u256(offsets.first) << Instruction::ADD << u256(offsets.second);
Type const* memberType = structType->memberType(names[i]);
StorageItem(m_context, *memberType).retrieveValue(SourceLocation(), true);
@ -370,7 +369,7 @@ bool ExpressionCompiler::visit(TupleExpression const& _tuple)
ArrayType const& arrayType = dynamic_cast<ArrayType const&>(*_tuple.annotation().type);
solAssert(!arrayType.isDynamicallySized(), "Cannot create dynamically sized inline array.");
utils().allocateMemory(max(u256(32u), arrayType.memoryDataSize()));
utils().allocateMemory(std::max(u256(32u), arrayType.memoryDataSize()));
m_context << Instruction::DUP1;
for (auto const& component: _tuple.components())
@ -383,7 +382,7 @@ bool ExpressionCompiler::visit(TupleExpression const& _tuple)
}
else
{
vector<unique_ptr<LValue>> lvalues;
std::vector<std::unique_ptr<LValue>> lvalues;
for (auto const& component: _tuple.components())
if (component)
{
@ -395,13 +394,13 @@ bool ExpressionCompiler::visit(TupleExpression const& _tuple)
}
}
else if (_tuple.annotation().willBeWrittenTo)
lvalues.push_back(unique_ptr<LValue>());
lvalues.push_back(std::unique_ptr<LValue>());
if (_tuple.annotation().willBeWrittenTo)
{
if (_tuple.components().size() == 1)
m_currentLValue = std::move(lvalues[0]);
else
m_currentLValue = make_unique<TupleObject>(m_context, std::move(lvalues));
m_currentLValue = std::make_unique<TupleObject>(m_context, std::move(lvalues));
}
}
return false;
@ -524,7 +523,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation)
m_context << u256(0) << Instruction::SUB;
break;
default:
solAssert(false, "Invalid unary operator: " + string(TokenTraits::toString(_unaryOperation.getOperator())));
solAssert(false, "Invalid unary operator: " + std::string(TokenTraits::toString(_unaryOperation.getOperator())));
}
return false;
}
@ -659,14 +658,14 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
TypePointers parameterTypes = functionType->parameterTypes();
vector<ASTPointer<Expression const>> const& arguments = _functionCall.sortedArguments();
std::vector<ASTPointer<Expression const>> const& arguments = _functionCall.sortedArguments();
if (functionCallKind == FunctionCallKind::StructConstructorCall)
{
TypeType const& type = dynamic_cast<TypeType const&>(*_functionCall.expression().annotation().type);
auto const& structType = dynamic_cast<StructType const&>(*type.actualType());
utils().allocateMemory(max(u256(32u), structType.memoryDataSize()));
utils().allocateMemory(std::max(u256(32u), structType.memoryDataSize()));
m_context << Instruction::DUP1;
for (unsigned i = 0; i < arguments.size(); ++i)
@ -992,7 +991,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
case FunctionType::Kind::Error:
{
_functionCall.expression().accept(*this);
vector<Type const*> argumentTypes;
std::vector<Type const*> argumentTypes;
for (ASTPointer<Expression const> const& arg: _functionCall.sortedArguments())
{
arg->accept(*this);
@ -1060,7 +1059,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
case FunctionType::Kind::RIPEMD160:
{
_functionCall.expression().accept(*this);
static map<FunctionType::Kind, u256> const contractAddresses{
static std::map<FunctionType::Kind, u256> const contractAddresses{
{FunctionType::Kind::ECRecover, 1},
{FunctionType::Kind::SHA256, 2},
{FunctionType::Kind::RIPEMD160, 3}
@ -1151,8 +1150,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
case FunctionType::Kind::BytesConcat:
{
_functionCall.expression().accept(*this);
vector<Type const*> argumentTypes;
vector<Type const*> targetTypes;
std::vector<Type const*> argumentTypes;
std::vector<Type const*> targetTypes;
for (auto const& argument: arguments)
{
argument->accept(*this);
@ -1416,7 +1415,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
// stack: <memory pointer> <selector>
// load current memory, mask and combine the selector
string mask = formatNumber((u256(-1) >> 32));
std::string mask = formatNumber((u256(-1) >> 32));
m_context.appendInlineAssembly(R"({
let data_start := add(mem_ptr, 0x20)
let data := mload(data_start)
@ -1476,7 +1475,7 @@ bool ExpressionCompiler::visit(FunctionCallOptions const& _functionCallOptions)
// Desired Stack: [salt], [gas], [value]
enum Option { Salt, Gas, Value };
vector<Option> presentOptions;
std::vector<Option> presentOptions;
FunctionType const& funType = dynamic_cast<FunctionType const&>(
*_functionCallOptions.expression().annotation().type
);
@ -1486,7 +1485,7 @@ bool ExpressionCompiler::visit(FunctionCallOptions const& _functionCallOptions)
for (size_t i = 0; i < _functionCallOptions.options().size(); ++i)
{
string const& name = *_functionCallOptions.names()[i];
std::string const& name = *_functionCallOptions.names()[i];
Type const* requiredType = TypeProvider::uint256();
Option newOption;
if (name == "salt")
@ -1818,7 +1817,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
);
m_context << Instruction::EXTCODEHASH;
}
else if ((set<string>{"send", "transfer"}).count(member))
else if ((std::set<std::string>{"send", "transfer"}).count(member))
{
solAssert(dynamic_cast<AddressType const&>(*_memberAccess.expression().annotation().type).stateMutability() == StateMutability::Payable, "");
utils().convertType(
@ -1827,7 +1826,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
true
);
}
else if ((set<string>{"call", "callcode", "delegatecall", "staticcall"}).count(member))
else if ((std::set<std::string>{"call", "callcode", "delegatecall", "staticcall"}).count(member))
utils().convertType(
*_memberAccess.expression().annotation().type,
*TypeProvider::address(),
@ -1910,7 +1909,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
Whiskers(R"({
mstore(start, sub(end, add(start, 0x20)))
mstore(<free>, and(add(end, 31), not(31)))
})")("free", to_string(CompilerUtils::freeMemoryPointer)).render(),
})")("free", std::to_string(CompilerUtils::freeMemoryPointer)).render(),
{"start", "end"}
);
m_context << Instruction::POP;
@ -1946,7 +1945,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
solAssert(false, "min/max not available for the given type.");
}
else if ((set<string>{"encode", "encodePacked", "encodeWithSelector", "encodeWithSignature", "decode"}).count(member))
else if ((std::set<std::string>{"encode", "encodePacked", "encodeWithSelector", "encodeWithSignature", "decode"}).count(member))
{
// no-op
}
@ -1961,7 +1960,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
{
case DataLocation::Storage:
{
pair<u256, unsigned> const& offsets = type.storageOffsetsOfMember(member);
std::pair<u256, unsigned> const& offsets = type.storageOffsetsOfMember(member);
m_context << offsets.first << Instruction::ADD << u256(offsets.second);
setLValueToStorageItem(_memberAccess);
break;
@ -2454,7 +2453,7 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token _operator, Type cons
IntegerType const& type = dynamic_cast<IntegerType const&>(_type);
if (m_context.arithmetic() == Arithmetic::Checked)
{
string functionName;
std::string functionName;
switch (_operator)
{
case Token::Add:
@ -2620,7 +2619,7 @@ void ExpressionCompiler::appendExpOperatorCode(Type const& _valueType, Type cons
void ExpressionCompiler::appendExternalFunctionCall(
FunctionType const& _functionType,
vector<ASTPointer<Expression const>> const& _arguments,
std::vector<ASTPointer<Expression const>> const& _arguments,
bool _tryCall
)
{

View File

@ -30,7 +30,6 @@
#include <libsolutil/StackTooDeepString.h>
using namespace std;
using namespace solidity;
using namespace solidity::evmasm;
using namespace solidity::frontend;
@ -410,7 +409,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
if (sourceType.location() == DataLocation::Storage)
{
// stack layout: source_ref target_ref
pair<u256, unsigned> const& offsets = sourceType.storageOffsetsOfMember(member.name);
std::pair<u256, unsigned> const& offsets = sourceType.storageOffsetsOfMember(member.name);
m_context << offsets.first << Instruction::DUP3 << Instruction::ADD;
m_context << u256(offsets.second);
// stack: source_ref target_ref source_member_ref source_member_off
@ -427,7 +426,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
// stack layout: source_ref target_ref source_value...
}
unsigned stackSize = sourceMemberType->sizeOnStack();
pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member.name);
std::pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member.name);
m_context << dupInstruction(1 + stackSize) << offsets.first << Instruction::ADD;
m_context << u256(offsets.second);
// stack: source_ref target_ref target_off source_value... target_member_ref target_member_byte_off
@ -469,7 +468,7 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const
Type const* memberType = member.type;
if (memberType->category() == Type::Category::Mapping)
continue;
pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member.name);
std::pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member.name);
m_context
<< offsets.first << Instruction::DUP3 << Instruction::ADD
<< u256(offsets.second);
@ -592,7 +591,7 @@ void TupleObject::storeValue(Type const& _sourceType, SourceLocation const& _loc
// We will assign from right to left to optimize stack layout.
for (size_t i = 0; i < m_lvalues.size(); ++i)
{
unique_ptr<LValue> const& lvalue = m_lvalues[m_lvalues.size() - i - 1];
std::unique_ptr<LValue> const& lvalue = m_lvalues[m_lvalues.size() - i - 1];
Type const* valType = valueTypes[valueTypes.size() - i - 1];
unsigned stackHeight = m_context.stackHeight();
solAssert(!valType == !lvalue, "");

View File

@ -26,44 +26,43 @@
#include <libsolutil/Whiskers.h>
#include <libsolutil/StringUtils.h>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
using namespace solidity::util;
string MultiUseYulFunctionCollector::requestedFunctions()
std::string MultiUseYulFunctionCollector::requestedFunctions()
{
string result = std::move(m_code);
std::string result = std::move(m_code);
m_code.clear();
m_requestedFunctions.clear();
return result;
}
string MultiUseYulFunctionCollector::createFunction(string const& _name, function<string ()> const& _creator)
std::string MultiUseYulFunctionCollector::createFunction(std::string const& _name, std::function<std::string()> const& _creator)
{
if (!m_requestedFunctions.count(_name))
{
m_requestedFunctions.insert(_name);
string fun = _creator();
std::string fun = _creator();
solAssert(!fun.empty(), "");
solAssert(fun.find("function " + _name + "(") != string::npos, "Function not properly named.");
solAssert(fun.find("function " + _name + "(") != std::string::npos, "Function not properly named.");
m_code += std::move(fun);
}
return _name;
}
string MultiUseYulFunctionCollector::createFunction(
string const& _name,
function<string(vector<string>&, vector<string>&)> const& _creator
std::string MultiUseYulFunctionCollector::createFunction(
std::string const& _name,
std::function<std::string(std::vector<std::string>&, std::vector<std::string>&)> const& _creator
)
{
solAssert(!_name.empty(), "");
if (!m_requestedFunctions.count(_name))
{
m_requestedFunctions.insert(_name);
vector<string> arguments;
vector<string> returnParameters;
string body = _creator(arguments, returnParameters);
std::vector<std::string> arguments;
std::vector<std::string> returnParameters;
std::string body = _creator(arguments, returnParameters);
solAssert(!body.empty(), "");
m_code += Whiskers(R"(

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,6 @@
#include <libyul/AsmPrinter.h>
using namespace std;
using namespace solidity::langutil;
using namespace solidity::frontend;
using namespace solidity::util;
@ -41,110 +40,110 @@ YulArity YulArity::fromType(FunctionType const& _functionType)
};
}
string IRNames::externalFunctionABIWrapper(Declaration const& _functionOrVarDecl)
std::string IRNames::externalFunctionABIWrapper(Declaration const& _functionOrVarDecl)
{
if (auto const* function = dynamic_cast<FunctionDefinition const*>(&_functionOrVarDecl))
solAssert(!function->isConstructor());
return "external_fun_" + _functionOrVarDecl.name() + "_" + to_string(_functionOrVarDecl.id());
return "external_fun_" + _functionOrVarDecl.name() + "_" + std::to_string(_functionOrVarDecl.id());
}
string IRNames::function(FunctionDefinition const& _function)
std::string IRNames::function(FunctionDefinition const& _function)
{
if (_function.isConstructor())
return constructor(*_function.annotation().contract);
return "fun_" + _function.name() + "_" + to_string(_function.id());
return "fun_" + _function.name() + "_" + std::to_string(_function.id());
}
string IRNames::function(VariableDeclaration const& _varDecl)
std::string IRNames::function(VariableDeclaration const& _varDecl)
{
return "getter_fun_" + _varDecl.name() + "_" + to_string(_varDecl.id());
return "getter_fun_" + _varDecl.name() + "_" + std::to_string(_varDecl.id());
}
string IRNames::modifierInvocation(ModifierInvocation const& _modifierInvocation)
std::string IRNames::modifierInvocation(ModifierInvocation const& _modifierInvocation)
{
// This uses the ID of the modifier invocation because it has to be unique
// for each invocation.
solAssert(!_modifierInvocation.name().path().empty(), "");
string const& modifierName = _modifierInvocation.name().path().back();
std::string const& modifierName = _modifierInvocation.name().path().back();
solAssert(!modifierName.empty(), "");
return "modifier_" + modifierName + "_" + to_string(_modifierInvocation.id());
return "modifier_" + modifierName + "_" + std::to_string(_modifierInvocation.id());
}
string IRNames::functionWithModifierInner(FunctionDefinition const& _function)
std::string IRNames::functionWithModifierInner(FunctionDefinition const& _function)
{
return "fun_" + _function.name() + "_" + to_string(_function.id()) + "_inner";
return "fun_" + _function.name() + "_" + std::to_string(_function.id()) + "_inner";
}
string IRNames::creationObject(ContractDefinition const& _contract)
std::string IRNames::creationObject(ContractDefinition const& _contract)
{
return _contract.name() + "_" + toString(_contract.id());
}
string IRNames::deployedObject(ContractDefinition const& _contract)
std::string IRNames::deployedObject(ContractDefinition const& _contract)
{
return _contract.name() + "_" + toString(_contract.id()) + "_deployed";
}
string IRNames::internalDispatch(YulArity const& _arity)
std::string IRNames::internalDispatch(YulArity const& _arity)
{
return "dispatch_internal"
"_in_" + to_string(_arity.in) +
"_out_" + to_string(_arity.out);
"_in_" + std::to_string(_arity.in) +
"_out_" + std::to_string(_arity.out);
}
string IRNames::constructor(ContractDefinition const& _contract)
std::string IRNames::constructor(ContractDefinition const& _contract)
{
return "constructor_" + _contract.name() + "_" + to_string(_contract.id());
return "constructor_" + _contract.name() + "_" + std::to_string(_contract.id());
}
string IRNames::libraryAddressImmutable()
std::string IRNames::libraryAddressImmutable()
{
return "library_deploy_address";
}
string IRNames::constantValueFunction(VariableDeclaration const& _constant)
std::string IRNames::constantValueFunction(VariableDeclaration const& _constant)
{
solAssert(_constant.isConstant(), "");
return "constant_" + _constant.name() + "_" + to_string(_constant.id());
return "constant_" + _constant.name() + "_" + std::to_string(_constant.id());
}
string IRNames::localVariable(VariableDeclaration const& _declaration)
std::string IRNames::localVariable(VariableDeclaration const& _declaration)
{
return "var_" + _declaration.name() + '_' + std::to_string(_declaration.id());
}
string IRNames::localVariable(Expression const& _expression)
std::string IRNames::localVariable(Expression const& _expression)
{
return "expr_" + to_string(_expression.id());
return "expr_" + std::to_string(_expression.id());
}
string IRNames::trySuccessConditionVariable(Expression const& _expression)
std::string IRNames::trySuccessConditionVariable(Expression const& _expression)
{
auto annotation = dynamic_cast<FunctionCallAnnotation const*>(&_expression.annotation());
solAssert(annotation, "");
solAssert(annotation->tryCall, "Parameter must be a FunctionCall with tryCall-annotation set.");
return "trySuccessCondition_" + to_string(_expression.id());
return "trySuccessCondition_" + std::to_string(_expression.id());
}
string IRNames::tupleComponent(size_t _i)
std::string IRNames::tupleComponent(size_t _i)
{
return "component_" + to_string(_i + 1);
return "component_" + std::to_string(_i + 1);
}
string IRNames::zeroValue(Type const& _type, string const& _variableName)
std::string IRNames::zeroValue(Type const& _type, std::string const& _variableName)
{
return "zero_" + _type.identifier() + _variableName;
}
string dispenseLocationComment(langutil::SourceLocation const& _location, IRGenerationContext& _context)
std::string dispenseLocationComment(langutil::SourceLocation const& _location, IRGenerationContext& _context)
{
solAssert(_location.sourceName, "");
_context.markSourceUsed(*_location.sourceName);
string debugInfo = AsmPrinter::formatSourceLocation(
std::string debugInfo = AsmPrinter::formatSourceLocation(
_location,
_context.sourceIndices(),
_context.debugInfoSelection(),
@ -154,7 +153,7 @@ string dispenseLocationComment(langutil::SourceLocation const& _location, IRGene
return debugInfo.empty() ? "" : "/// " + debugInfo;
}
string dispenseLocationComment(ASTNode const& _node, IRGenerationContext& _context)
std::string dispenseLocationComment(ASTNode const& _node, IRGenerationContext& _context)
{
return dispenseLocationComment(_node.location(), _context);
}

View File

@ -32,14 +32,13 @@
#include <range/v3/view/map.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::frontend;
string IRGenerationContext::enqueueFunctionForCodeGeneration(FunctionDefinition const& _function)
std::string IRGenerationContext::enqueueFunctionForCodeGeneration(FunctionDefinition const& _function)
{
string name = IRNames::function(_function);
std::string name = IRNames::function(_function);
if (!m_functions.contains(name))
m_functionGenerationQueue.insert(&_function);
@ -121,12 +120,12 @@ void IRGenerationContext::addStateVariable(
unsigned _byteOffset
)
{
m_stateVariables[&_declaration] = make_pair(std::move(_storageOffset), _byteOffset);
m_stateVariables[&_declaration] = std::make_pair(std::move(_storageOffset), _byteOffset);
}
string IRGenerationContext::newYulVariable()
std::string IRGenerationContext::newYulVariable()
{
return "_" + to_string(++m_varCounter);
return "_" + std::to_string(++m_varCounter);
}
void IRGenerationContext::initializeInternalDispatch(InternalDispatchMap _internalDispatch)

View File

@ -38,25 +38,23 @@
#include <libsolutil/StringUtils.h>
#include <libsolutil/Whiskers.h>
#include <liblangutil/SourceReferenceFormatter.h>
#include <json/json.h>
#include <sstream>
#include <variant>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
using namespace solidity::langutil;
using namespace solidity::util;
using namespace std::string_literals;
namespace
{
void verifyCallGraph(
set<CallableDeclaration const*, ASTNode::CompareByID> const& _expectedCallables,
set<FunctionDefinition const*> _generatedFunctions
std::set<CallableDeclaration const*, ASTNode::CompareByID> const& _expectedCallables,
std::set<FunctionDefinition const*> _generatedFunctions
)
{
for (auto const& expectedCallable: _expectedCallables)
@ -75,47 +73,47 @@ void verifyCallGraph(
);
}
set<CallableDeclaration const*, ASTNode::CompareByID> collectReachableCallables(
std::set<CallableDeclaration const*, ASTNode::CompareByID> collectReachableCallables(
CallGraph const& _graph
)
{
set<CallableDeclaration const*, ASTNode::CompareByID> reachableCallables;
std::set<CallableDeclaration const*, ASTNode::CompareByID> reachableCallables;
for (CallGraph::Node const& reachableNode: _graph.edges | ranges::views::keys)
if (holds_alternative<CallableDeclaration const*>(reachableNode))
reachableCallables.emplace(get<CallableDeclaration const*>(reachableNode));
if (std::holds_alternative<CallableDeclaration const*>(reachableNode))
reachableCallables.emplace(std::get<CallableDeclaration const*>(reachableNode));
return reachableCallables;
}
}
string IRGenerator::run(
std::string IRGenerator::run(
ContractDefinition const& _contract,
bytes const& _cborMetadata,
map<ContractDefinition const*, string_view const> const& _otherYulSources
std::map<ContractDefinition const*, std::string_view const> const& _otherYulSources
)
{
return yul::reindent(generate(_contract, _cborMetadata, _otherYulSources));
}
string IRGenerator::generate(
std::string IRGenerator::generate(
ContractDefinition const& _contract,
bytes const& _cborMetadata,
map<ContractDefinition const*, string_view const> const& _otherYulSources
std::map<ContractDefinition const*, std::string_view const> const& _otherYulSources
)
{
auto subObjectSources = [&_otherYulSources](std::set<ContractDefinition const*, ASTNode::CompareByID> const& subObjects) -> string
auto subObjectSources = [&_otherYulSources](std::set<ContractDefinition const*, ASTNode::CompareByID> const& subObjects) -> std::string
{
std::string subObjectsSources;
for (ContractDefinition const* subObject: subObjects)
subObjectsSources += _otherYulSources.at(subObject);
return subObjectsSources;
};
auto formatUseSrcMap = [](IRGenerationContext const& _context) -> string
auto formatUseSrcMap = [](IRGenerationContext const& _context) -> std::string
{
return joinHumanReadable(
ranges::views::transform(_context.usedSourceNames(), [_context](string const& _sourceName) {
return to_string(_context.sourceIndices().at(_sourceName)) + ":" + escapeAndQuoteString(_sourceName);
ranges::views::transform(_context.usedSourceNames(), [_context](std::string const& _sourceName) {
return std::to_string(_context.sourceIndices().at(_sourceName)) + ":" + escapeAndQuoteString(_sourceName);
}),
", "
);
@ -164,7 +162,7 @@ string IRGenerator::generate(
FunctionDefinition const* constructor = _contract.constructor();
t("callValueCheck", !constructor || !constructor->isPayable() ? callValueCheck() : "");
vector<string> constructorParams;
std::vector<std::string> constructorParams;
if (constructor && !constructor->parameters().empty())
{
for (size_t i = 0; i < CompilerUtils::sizeOnStack(constructor->parameters()); ++i)
@ -180,7 +178,7 @@ string IRGenerator::generate(
t("deploy", deployCode(_contract));
generateConstructors(_contract);
set<FunctionDefinition const*> creationFunctionList = generateQueuedFunctions();
std::set<FunctionDefinition const*> creationFunctionList = generateQueuedFunctions();
InternalDispatchMap internalDispatchMap = generateInternalDispatchFunctions(_contract);
t("functions", m_context.functionCollector().requestedFunctions());
@ -203,7 +201,7 @@ string IRGenerator::generate(
t("sourceLocationCommentDeployed", dispenseLocationComment(_contract));
t("library_address", IRNames::libraryAddressImmutable());
t("dispatch", dispatchRoutine(_contract));
set<FunctionDefinition const*> deployedFunctionList = generateQueuedFunctions();
std::set<FunctionDefinition const*> deployedFunctionList = generateQueuedFunctions();
generateInternalDispatchFunctions(_contract);
t("deployedFunctions", m_context.functionCollector().requestedFunctions());
t("deployedSubObjects", subObjectSources(m_context.subObjectsCreated()));
@ -224,16 +222,16 @@ string IRGenerator::generate(
return t.render();
}
string IRGenerator::generate(Block const& _block)
std::string IRGenerator::generate(Block const& _block)
{
IRGeneratorForStatements generator(m_context, m_utils);
generator.generate(_block);
return generator.code();
}
set<FunctionDefinition const*> IRGenerator::generateQueuedFunctions()
std::set<FunctionDefinition const*> IRGenerator::generateQueuedFunctions()
{
set<FunctionDefinition const*> functions;
std::set<FunctionDefinition const*> functions;
while (!m_context.functionGenerationQueueEmpty())
{
@ -258,7 +256,7 @@ InternalDispatchMap IRGenerator::generateInternalDispatchFunctions(ContractDefin
InternalDispatchMap internalDispatchMap = m_context.consumeInternalDispatchMap();
for (YulArity const& arity: internalDispatchMap | ranges::views::keys)
{
string funName = IRNames::internalDispatch(arity);
std::string funName = IRNames::internalDispatch(arity);
m_context.functionCollector().createFunction(funName, [&]() {
Whiskers templ(R"(
<sourceLocationComment>
@ -280,7 +278,7 @@ InternalDispatchMap IRGenerator::generateInternalDispatchFunctions(ContractDefin
templ("in", suffixedVariableNameList("in_", 0, arity.in));
templ("out", suffixedVariableNameList("out_", 0, arity.out));
vector<map<string, string>> cases;
std::vector<std::map<std::string, std::string>> cases;
for (FunctionDefinition const* function: internalDispatchMap.at(arity))
{
solAssert(function, "");
@ -293,8 +291,8 @@ InternalDispatchMap IRGenerator::generateInternalDispatchFunctions(ContractDefin
solAssert(function->id() != 0, "Unexpected function ID: 0");
solAssert(m_context.functionCollector().contains(IRNames::function(*function)), "");
cases.emplace_back(map<string, string>{
{"funID", to_string(m_context.mostDerivedContract().annotation().internalFunctionIDs.at(function))},
cases.emplace_back(std::map<std::string, std::string>{
{"funID", std::to_string(m_context.mostDerivedContract().annotation().internalFunctionIDs.at(function))},
{"name", IRNames::function(*function)}
});
}
@ -313,9 +311,9 @@ InternalDispatchMap IRGenerator::generateInternalDispatchFunctions(ContractDefin
return internalDispatchMap;
}
string IRGenerator::generateFunction(FunctionDefinition const& _function)
std::string IRGenerator::generateFunction(FunctionDefinition const& _function)
{
string functionName = IRNames::function(_function);
std::string functionName = IRNames::function(_function);
return m_context.functionCollector().createFunction(functionName, [&]() {
m_context.resetLocalVariables();
Whiskers t(R"(
@ -328,7 +326,7 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function)
)");
if (m_context.debugInfoSelection().astID)
t("astIDComment", "/// @ast-id " + to_string(_function.id()) + "\n");
t("astIDComment", "/// @ast-id " + std::to_string(_function.id()) + "\n");
else
t("astIDComment", "");
t("sourceLocationComment", dispenseLocationComment(_function));
@ -338,12 +336,12 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function)
);
t("functionName", functionName);
vector<string> params;
std::vector<std::string> params;
for (auto const& varDecl: _function.parameters())
params += m_context.addLocalVariable(*varDecl).stackSlots();
t("params", joinHumanReadable(params));
vector<string> retParams;
string retInit;
std::vector<std::string> retParams;
std::string retInit;
for (auto const& varDecl: _function.returnParameters())
{
retParams += m_context.addLocalVariable(*varDecl).stackSlots();
@ -360,14 +358,14 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function)
for (size_t i = 0; i < _function.modifiers().size(); ++i)
{
ModifierInvocation const& modifier = *_function.modifiers().at(i);
string next =
std::string next =
i + 1 < _function.modifiers().size() ?
IRNames::modifierInvocation(*_function.modifiers().at(i + 1)) :
IRNames::functionWithModifierInner(_function);
generateModifier(modifier, _function, next);
}
t("body",
(retParams.empty() ? string{} : joinHumanReadable(retParams) + " := ") +
(retParams.empty() ? std::string{} : joinHumanReadable(retParams) + " := ") +
IRNames::modifierInvocation(*_function.modifiers().at(0)) +
"(" +
joinHumanReadable(retParams + params) +
@ -380,13 +378,13 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function)
});
}
string IRGenerator::generateModifier(
std::string IRGenerator::generateModifier(
ModifierInvocation const& _modifierInvocation,
FunctionDefinition const& _function,
string const& _nextFunction
std::string const& _nextFunction
)
{
string functionName = IRNames::modifierInvocation(_modifierInvocation);
std::string functionName = IRNames::modifierInvocation(_modifierInvocation);
return m_context.functionCollector().createFunction(functionName, [&]() {
m_context.resetLocalVariables();
Whiskers t(R"(
@ -400,15 +398,15 @@ string IRGenerator::generateModifier(
)");
t("functionName", functionName);
vector<string> retParamsIn;
std::vector<std::string> retParamsIn;
for (auto const& varDecl: _function.returnParameters())
retParamsIn += m_context.addLocalVariable(*varDecl).stackSlots();
vector<string> params = retParamsIn;
std::vector<std::string> params = retParamsIn;
for (auto const& varDecl: _function.parameters())
params += m_context.addLocalVariable(*varDecl).stackSlots();
t("params", joinHumanReadable(params));
vector<string> retParams;
string assignRetParams;
std::vector<std::string> retParams;
std::string assignRetParams;
for (size_t i = 0; i < retParamsIn.size(); ++i)
{
retParams.emplace_back(m_context.newYulVariable());
@ -423,7 +421,7 @@ string IRGenerator::generateModifier(
solAssert(modifier, "");
if (m_context.debugInfoSelection().astID)
t("astIDComment", "/// @ast-id " + to_string(modifier->id()) + "\n");
t("astIDComment", "/// @ast-id " + std::to_string(modifier->id()) + "\n");
else
t("astIDComment", "");
t("sourceLocationComment", dispenseLocationComment(*modifier));
@ -465,7 +463,7 @@ string IRGenerator::generateModifier(
t("evalArgs", expressionEvaluator.code());
IRGeneratorForStatements generator(m_context, m_utils, [&]() {
string ret = joinHumanReadable(retParams);
std::string ret = joinHumanReadable(retParams);
return
(ret.empty() ? "" : ret + " := ") +
_nextFunction + "(" + joinHumanReadable(params) + ")\n";
@ -476,9 +474,9 @@ string IRGenerator::generateModifier(
});
}
string IRGenerator::generateFunctionWithModifierInner(FunctionDefinition const& _function)
std::string IRGenerator::generateFunctionWithModifierInner(FunctionDefinition const& _function)
{
string functionName = IRNames::functionWithModifierInner(_function);
std::string functionName = IRNames::functionWithModifierInner(_function);
return m_context.functionCollector().createFunction(functionName, [&]() {
m_context.resetLocalVariables();
Whiskers t(R"(
@ -495,17 +493,17 @@ string IRGenerator::generateFunctionWithModifierInner(FunctionDefinition const&
dispenseLocationComment(m_context.mostDerivedContract())
);
t("functionName", functionName);
vector<string> retParams;
vector<string> retParamsIn;
std::vector<std::string> retParams;
std::vector<std::string> retParamsIn;
for (auto const& varDecl: _function.returnParameters())
retParams += m_context.addLocalVariable(*varDecl).stackSlots();
string assignRetParams;
std::string assignRetParams;
for (size_t i = 0; i < retParams.size(); ++i)
{
retParamsIn.emplace_back(m_context.newYulVariable());
assignRetParams += retParams.at(i) + " := " + retParamsIn.at(i) + "\n";
}
vector<string> params = retParamsIn;
std::vector<std::string> params = retParamsIn;
for (auto const& varDecl: _function.parameters())
params += m_context.addLocalVariable(*varDecl).stackSlots();
t("params", joinHumanReadable(params));
@ -516,9 +514,9 @@ string IRGenerator::generateFunctionWithModifierInner(FunctionDefinition const&
});
}
string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
std::string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
{
string functionName = IRNames::function(_varDecl);
std::string functionName = IRNames::function(_varDecl);
return m_context.functionCollector().createFunction(functionName, [&]() {
Type const* type = _varDecl.annotation().type;
@ -540,7 +538,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
(
"astIDComment",
m_context.debugInfoSelection().astID ?
"/// @ast-id " + to_string(_varDecl.id()) + "\n" :
"/// @ast-id " + std::to_string(_varDecl.id()) + "\n" :
""
)
("sourceLocationComment", dispenseLocationComment(_varDecl))
@ -549,7 +547,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
dispenseLocationComment(m_context.mostDerivedContract())
)
("functionName", functionName)
("id", to_string(_varDecl.id()))
("id", std::to_string(_varDecl.id()))
.render();
}
else if (_varDecl.isConstant())
@ -565,7 +563,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
(
"astIDComment",
m_context.debugInfoSelection().astID ?
"/// @ast-id " + to_string(_varDecl.id()) + "\n" :
"/// @ast-id " + std::to_string(_varDecl.id()) + "\n" :
""
)
("sourceLocationComment", dispenseLocationComment(_varDecl))
@ -579,7 +577,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
.render();
}
string code;
std::string code;
auto const& location = m_context.storageLocationOfStateVariable(_varDecl);
code += Whiskers(R"(
@ -587,7 +585,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
let offset := <offset>
)")
("slot", location.first.str())
("offset", to_string(location.second))
("offset", std::to_string(location.second))
.render();
if (!paramTypes.empty())
@ -603,8 +601,8 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
// The initial value of @a currentType is only used if we skip the loop completely.
Type const* currentType = _varDecl.annotation().type;
vector<string> parameters;
vector<string> returnVariables;
std::vector<std::string> parameters;
std::vector<std::string> returnVariables;
for (size_t i = 0; i < paramTypes.size(); ++i)
{
@ -612,7 +610,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
ArrayType const* arrayType = dynamic_cast<ArrayType const*>(currentType);
solAssert(mappingType || arrayType, "");
vector<string> keys = IRVariable("key_" + to_string(i),
std::vector<std::string> keys = IRVariable("key_" + std::to_string(i),
mappingType ? *mappingType->keyType() : *TypeProvider::uint256()
).stackSlots();
parameters += keys;
@ -655,8 +653,8 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
)
continue;
pair<u256, unsigned> const& offsets = structType->storageOffsetsOfMember(names[i]);
vector<string> retVars = IRVariable("ret_" + to_string(returnVariables.size()), *returnTypes[i]).stackSlots();
std::pair<u256, unsigned> const& offsets = structType->storageOffsetsOfMember(names[i]);
std::vector<std::string> retVars = IRVariable("ret_" + std::to_string(returnVariables.size()), *returnTypes[i]).stackSlots();
returnVariables += retVars;
code += Whiskers(R"(
<ret> := <readStorage>(add(slot, <slotOffset>))
@ -673,7 +671,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
auto const* arrayType = dynamic_cast<ArrayType const*>(returnTypes.front());
if (arrayType)
solAssert(arrayType->isByteArrayOrString(), "");
vector<string> retVars = IRVariable("ret", *returnTypes.front()).stackSlots();
std::vector<std::string> retVars = IRVariable("ret", *returnTypes.front()).stackSlots();
returnVariables += retVars;
code += Whiskers(R"(
<ret> := <readStorage>(slot, offset)
@ -697,7 +695,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
(
"astIDComment",
m_context.debugInfoSelection().astID ?
"/// @ast-id " + to_string(_varDecl.id()) + "\n" :
"/// @ast-id " + std::to_string(_varDecl.id()) + "\n" :
""
)
("sourceLocationComment", dispenseLocationComment(_varDecl))
@ -709,10 +707,10 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
});
}
string IRGenerator::generateExternalFunction(ContractDefinition const& _contract, FunctionType const& _functionType)
std::string IRGenerator::generateExternalFunction(ContractDefinition const& _contract, FunctionType const& _functionType)
{
string functionName = IRNames::externalFunctionABIWrapper(_functionType.declaration());
return m_context.functionCollector().createFunction(functionName, [&](vector<string>&, vector<string>&) -> string {
std::string functionName = IRNames::externalFunctionABIWrapper(_functionType.declaration());
return m_context.functionCollector().createFunction(functionName, [&](std::vector<std::string>&, std::vector<std::string>&) -> std::string {
Whiskers t(R"X(
<callValueCheck>
<?+params>let <params> := </+params> <abiDecode>(4, calldatasize())
@ -723,8 +721,8 @@ string IRGenerator::generateExternalFunction(ContractDefinition const& _contract
)X");
t("callValueCheck", (_functionType.isPayable() || _contract.isLibrary()) ? "" : callValueCheck());
unsigned paramVars = make_shared<TupleType>(_functionType.parameterTypes())->sizeOnStack();
unsigned retVars = make_shared<TupleType>(_functionType.returnParameterTypes())->sizeOnStack();
unsigned paramVars = std::make_shared<TupleType>(_functionType.parameterTypes())->sizeOnStack();
unsigned retVars = std::make_shared<TupleType>(_functionType.returnParameterTypes())->sizeOnStack();
ABIFunctions abiFunctions(m_evmVersion, m_context.revertStrings(), m_context.functionCollector());
t("abiDecode", abiFunctions.tupleDecoder(_functionType.parameterTypes()));
@ -747,14 +745,14 @@ string IRGenerator::generateExternalFunction(ContractDefinition const& _contract
});
}
string IRGenerator::generateInitialAssignment(VariableDeclaration const& _varDecl)
std::string IRGenerator::generateInitialAssignment(VariableDeclaration const& _varDecl)
{
IRGeneratorForStatements generator(m_context, m_utils);
generator.initializeLocalVar(_varDecl);
return generator.code();
}
pair<string, map<ContractDefinition const*, vector<string>>> IRGenerator::evaluateConstructorArguments(
std::pair<std::string, std::map<ContractDefinition const*, std::vector<std::string>>> IRGenerator::evaluateConstructorArguments(
ContractDefinition const& _contract
)
{
@ -767,12 +765,12 @@ pair<string, map<ContractDefinition const*, vector<string>>> IRGenerator::evalua
auto it2 = find(linearizedBaseContracts.begin(), linearizedBaseContracts.end(), _c2);
return it1 < it2;
}
vector<ContractDefinition const*> const& linearizedBaseContracts;
std::vector<ContractDefinition const*> const& linearizedBaseContracts;
} inheritanceOrder{_contract.annotation().linearizedBaseContracts};
map<ContractDefinition const*, vector<string>> constructorParams;
std::map<ContractDefinition const*, std::vector<std::string>> constructorParams;
map<ContractDefinition const*, std::vector<ASTPointer<Expression>>const *, InheritanceOrder>
std::map<ContractDefinition const*, std::vector<ASTPointer<Expression>>const *, InheritanceOrder>
baseConstructorArguments(inheritanceOrder);
for (ASTPointer<InheritanceSpecifier> const& base: _contract.baseContracts())
@ -804,7 +802,7 @@ pair<string, map<ContractDefinition const*, vector<string>>> IRGenerator::evalua
solAssert(baseContract && arguments, "");
if (baseContract->constructor() && !arguments->empty())
{
vector<string> params;
std::vector<std::string> params;
for (size_t i = 0; i < arguments->size(); ++i)
params += generator.evaluateExpression(
*(arguments->at(i)),
@ -817,7 +815,7 @@ pair<string, map<ContractDefinition const*, vector<string>>> IRGenerator::evalua
return {generator.code(), constructorParams};
}
string IRGenerator::initStateVariables(ContractDefinition const& _contract)
std::string IRGenerator::initStateVariables(ContractDefinition const& _contract)
{
IRGeneratorForStatements generator{m_context, m_utils};
for (VariableDeclaration const* variable: _contract.stateVariables())
@ -831,16 +829,16 @@ string IRGenerator::initStateVariables(ContractDefinition const& _contract)
void IRGenerator::generateConstructors(ContractDefinition const& _contract)
{
auto listAllParams =
[&](map<ContractDefinition const*, vector<string>> const& baseParams) -> vector<string>
[&](std::map<ContractDefinition const*, std::vector<std::string>> const& baseParams) -> std::vector<std::string>
{
vector<string> params;
std::vector<std::string> params;
for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts)
if (baseParams.count(contract))
params += baseParams.at(contract);
return params;
};
map<ContractDefinition const*, vector<string>> baseConstructorParams;
std::map<ContractDefinition const*, std::vector<std::string>> baseConstructorParams;
for (size_t i = 0; i < _contract.annotation().linearizedBaseContracts.size(); ++i)
{
ContractDefinition const* contract = _contract.annotation().linearizedBaseContracts[i];
@ -859,13 +857,13 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract)
}
<contractSourceLocationComment>
)");
vector<string> params;
std::vector<std::string> params;
if (contract->constructor())
for (ASTPointer<VariableDeclaration> const& varDecl: contract->constructor()->parameters())
params += m_context.addLocalVariable(*varDecl).stackSlots();
if (m_context.debugInfoSelection().astID && contract->constructor())
t("astIDComment", "/// @ast-id " + to_string(contract->constructor()->id()) + "\n");
t("astIDComment", "/// @ast-id " + std::to_string(contract->constructor()->id()) + "\n");
else
t("astIDComment", "");
t("sourceLocationComment", dispenseLocationComment(
@ -879,11 +877,11 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract)
);
t("params", joinHumanReadable(params));
vector<string> baseParams = listAllParams(baseConstructorParams);
std::vector<std::string> baseParams = listAllParams(baseConstructorParams);
t("baseParams", joinHumanReadable(baseParams));
t("comma", !params.empty() && !baseParams.empty() ? ", " : "");
t("functionName", IRNames::constructor(*contract));
pair<string, map<ContractDefinition const*, vector<string>>> evaluatedArgs = evaluateConstructorArguments(*contract);
std::pair<std::string, std::map<ContractDefinition const*, std::vector<std::string>>> evaluatedArgs = evaluateConstructorArguments(*contract);
baseConstructorParams.insert(evaluatedArgs.second.begin(), evaluatedArgs.second.end());
t("evalBaseArguments", evaluatedArgs.first);
if (i < _contract.annotation().linearizedBaseContracts.size() - 1)
@ -896,10 +894,10 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract)
else
t("hasNextConstructor", false);
t("initStateVariables", initStateVariables(*contract));
string body;
std::string body;
if (FunctionDefinition const* constructor = contract->constructor())
{
vector<ModifierInvocation*> realModifiers;
std::vector<ModifierInvocation*> realModifiers;
for (auto const& modifierInvocation: constructor->modifiers())
// Filter out the base constructor calls
if (dynamic_cast<ModifierDefinition const*>(modifierInvocation->name().annotation().referencedDeclaration))
@ -911,7 +909,7 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract)
for (size_t i = 0; i < realModifiers.size(); ++i)
{
ModifierInvocation const& modifier = *realModifiers.at(i);
string next =
std::string next =
i + 1 < realModifiers.size() ?
IRNames::modifierInvocation(*realModifiers.at(i + 1)) :
IRNames::functionWithModifierInner(*constructor);
@ -933,7 +931,7 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract)
}
}
string IRGenerator::deployCode(ContractDefinition const& _contract)
std::string IRGenerator::deployCode(ContractDefinition const& _contract)
{
Whiskers t(R"X(
let <codeOffset> := <allocateUnbounded>()
@ -947,11 +945,11 @@ string IRGenerator::deployCode(ContractDefinition const& _contract)
t("codeOffset", m_context.newYulVariable());
t("object", IRNames::deployedObject(_contract));
vector<map<string, string>> immutables;
std::vector<std::map<std::string, std::string>> immutables;
if (_contract.isLibrary())
{
solAssert(ContractType(_contract).immutableVariables().empty(), "");
immutables.emplace_back(map<string, string>{
immutables.emplace_back(std::map<std::string, std::string>{
{"immutableName"s, IRNames::libraryAddressImmutable()},
{"value"s, "address()"}
});
@ -962,21 +960,21 @@ string IRGenerator::deployCode(ContractDefinition const& _contract)
{
solUnimplementedAssert(immutable->type()->isValueType());
solUnimplementedAssert(immutable->type()->sizeOnStack() == 1);
immutables.emplace_back(map<string, string>{
{"immutableName"s, to_string(immutable->id())},
{"value"s, "mload(" + to_string(m_context.immutableMemoryOffset(*immutable)) + ")"}
immutables.emplace_back(std::map<std::string, std::string>{
{"immutableName"s, std::to_string(immutable->id())},
{"value"s, "mload(" + std::to_string(m_context.immutableMemoryOffset(*immutable)) + ")"}
});
}
t("immutables", std::move(immutables));
return t.render();
}
string IRGenerator::callValueCheck()
std::string IRGenerator::callValueCheck()
{
return "if callvalue() { " + m_utils.revertReasonIfDebugFunction("Ether sent to non-payable function") + "() }";
}
string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
std::string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
{
Whiskers t(R"X(
<?+cases>if iszero(lt(calldatasize(), 4))
@ -997,15 +995,15 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
<fallback>
)X");
t("shr224", m_utils.shiftRightFunction(224));
vector<map<string, string>> functions;
std::vector<std::map<std::string, std::string>> functions;
for (auto const& function: _contract.interfaceFunctions())
{
functions.emplace_back();
map<string, string>& templ = functions.back();
std::map<std::string, std::string>& templ = functions.back();
templ["functionSelector"] = "0x" + function.first.hex();
FunctionTypePointer const& type = function.second;
templ["functionName"] = type->externalSignature();
string delegatecallCheck;
std::string delegatecallCheck;
if (_contract.isLibrary())
{
solAssert(!type->isPayable(), "");
@ -1033,7 +1031,7 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
if (FunctionDefinition const* fallback = _contract.fallbackFunction())
{
solAssert(!_contract.isLibrary(), "");
string fallbackCode;
std::string fallbackCode;
if (!fallback->isPayable())
fallbackCode += callValueCheck() + "\n";
if (fallback->parameters().empty())
@ -1057,7 +1055,7 @@ string IRGenerator::dispatchRoutine(ContractDefinition const& _contract)
return t.render();
}
string IRGenerator::memoryInit(bool _useMemoryGuard)
std::string IRGenerator::memoryInit(bool _useMemoryGuard)
{
// This function should be called at the beginning of the EVM call frame
// and thus can assume all memory to be zero, including the contents of
@ -1068,10 +1066,10 @@ string IRGenerator::memoryInit(bool _useMemoryGuard)
"mstore(<memPtr>, memoryguard(<freeMemoryStart>))" :
"mstore(<memPtr>, <freeMemoryStart>)"
}
("memPtr", to_string(CompilerUtils::freeMemoryPointer))
("memPtr", std::to_string(CompilerUtils::freeMemoryPointer))
(
"freeMemoryStart",
to_string(CompilerUtils::generalPurposeMemoryStart + m_context.reservedMemory())
std::to_string(CompilerUtils::generalPurposeMemoryStart + m_context.reservedMemory())
).render();
}
@ -1101,10 +1099,10 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon
m_context.setMostDerivedContract(_contract);
for (auto const& var: ContractType(_contract).stateVariables())
m_context.addStateVariable(*get<0>(var), get<1>(var), get<2>(var));
m_context.addStateVariable(*std::get<0>(var), std::get<1>(var), std::get<2>(var));
}
string IRGenerator::dispenseLocationComment(ASTNode const& _node)
std::string IRGenerator::dispenseLocationComment(ASTNode const& _node)
{
return ::dispenseLocationComment(_node, m_context);
}

View File

@ -49,7 +49,6 @@
#include <range/v3/view/transform.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::frontend;
@ -95,8 +94,8 @@ struct CopyTranslate: public yul::ASTCopier
return ASTCopier::translate(_identifier);
yul::Expression translated = translateReference(_identifier);
solAssert(holds_alternative<yul::Identifier>(translated));
return get<yul::Identifier>(std::move(translated));
solAssert(std::holds_alternative<yul::Identifier>(translated));
return std::get<yul::Identifier>(std::move(translated));
}
private:
@ -109,9 +108,9 @@ private:
auto const& reference = m_references.at(&_identifier);
auto const varDecl = dynamic_cast<VariableDeclaration const*>(reference.declaration);
solUnimplementedAssert(varDecl);
string const& suffix = reference.suffix;
std::string const& suffix = reference.suffix;
string value;
std::string value;
if (suffix.empty() && varDecl->isLocalVariable())
{
auto const& var = m_context.localVariable(*varDecl);
@ -165,7 +164,7 @@ private:
if (suffix == "slot")
value = m_context.storageLocationOfStateVariable(*varDecl).first.str();
else if (suffix == "offset")
value = to_string(m_context.storageLocationOfStateVariable(*varDecl).second);
value = std::to_string(m_context.storageLocationOfStateVariable(*varDecl).second);
else
solAssert(false);
}
@ -216,7 +215,7 @@ private:
}
string IRGeneratorForStatementsBase::code() const
std::string IRGeneratorForStatementsBase::code() const
{
return m_code.str();
}
@ -240,7 +239,7 @@ void IRGeneratorForStatementsBase::setLocation(ASTNode const& _node)
m_currentLocation = _node.location();
}
string IRGeneratorForStatements::code() const
std::string IRGeneratorForStatements::code() const
{
solAssert(!m_currentLValue, "LValue not reset!");
return IRGeneratorForStatementsBase::code();
@ -338,11 +337,11 @@ IRVariable IRGeneratorForStatements::evaluateExpression(Expression const& _expre
}
}
string IRGeneratorForStatements::constantValueFunction(VariableDeclaration const& _constant)
std::string IRGeneratorForStatements::constantValueFunction(VariableDeclaration const& _constant)
{
try
{
string functionName = IRNames::constantValueFunction(_constant);
std::string functionName = IRNames::constantValueFunction(_constant);
return m_context.functionCollector().createFunction(functionName, [&] {
Whiskers templ(R"(
<sourceLocationComment>
@ -410,7 +409,7 @@ bool IRGeneratorForStatements::visit(Conditional const& _conditional)
setLocation(_conditional);
string condition = expressionAsType(_conditional.condition(), *TypeProvider::boolean());
std::string condition = expressionAsType(_conditional.condition(), *TypeProvider::boolean());
declare(_conditional);
appendCode() << "switch " << condition << "\n" "case 0 {\n";
@ -501,7 +500,7 @@ bool IRGeneratorForStatements::visit(TupleExpression const& _tuple)
_tuple.components().size() <<
")\n";
string mpos = IRVariable(_tuple).part("mpos").name();
std::string mpos = IRVariable(_tuple).part("mpos").name();
Type const& baseType = *arrayType.baseType();
for (size_t i = 0; i < _tuple.components().size(); i++)
{
@ -512,7 +511,7 @@ bool IRGeneratorForStatements::visit(TupleExpression const& _tuple)
appendCode() <<
m_utils.writeToMemoryFunction(baseType) <<
"(" <<
("add(" + mpos + ", " + to_string(i * arrayType.memoryStride()) + ")") <<
("add(" + mpos + ", " + std::to_string(i * arrayType.memoryStride()) + ")") <<
", " <<
converted.commaSeparatedList() <<
")\n";
@ -535,7 +534,7 @@ bool IRGeneratorForStatements::visit(TupleExpression const& _tuple)
}
else
{
vector<optional<IRLValue>> lvalues;
std::vector<std::optional<IRLValue>> lvalues;
for (size_t i = 0; i < _tuple.components().size(); ++i)
if (auto const& component = _tuple.components()[i])
{
@ -586,7 +585,7 @@ bool IRGeneratorForStatements::visit(IfStatement const& _ifStatement)
{
_ifStatement.condition().accept(*this);
setLocation(_ifStatement);
string condition = expressionAsType(_ifStatement.condition(), *TypeProvider::boolean());
std::string condition = expressionAsType(_ifStatement.condition(), *TypeProvider::boolean());
if (_ifStatement.falseStatement())
{
@ -658,7 +657,7 @@ void IRGeneratorForStatements::endVisit(Return const& _return)
if (Expression const* value = _return.expression())
{
solAssert(_return.annotation().functionReturnParameters, "Invalid return parameters pointer.");
vector<ASTPointer<VariableDeclaration>> const& returnParameters =
std::vector<ASTPointer<VariableDeclaration>> const& returnParameters =
_return.annotation().functionReturnParameters->parameters();
if (returnParameters.size() > 1)
for (size_t i = 0; i < returnParameters.size(); ++i)
@ -685,7 +684,7 @@ bool IRGeneratorForStatements::visit(UnaryOperation const& _unaryOperation)
solAssert(function->returnParameters().size() == 1);
solAssert(*function->returnParameters()[0]->type() == *_unaryOperation.annotation().type);
string argument = expressionAsType(_unaryOperation.subExpression(), *function->parameters()[0]->type());
std::string argument = expressionAsType(_unaryOperation.subExpression(), *function->parameters()[0]->type());
solAssert(!argument.empty());
solAssert(_unaryOperation.userDefinedFunctionType()->kind() == FunctionType::Kind::Internal);
@ -812,8 +811,8 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp)
solAssert(function->returnParameters().size() == 1);
solAssert(*function->returnParameters()[0]->type() == *_binOp.annotation().type);
string left = expressionAsType(_binOp.leftExpression(), *function->parameters()[0]->type());
string right = expressionAsType(_binOp.rightExpression(), *function->parameters()[1]->type());
std::string left = expressionAsType(_binOp.leftExpression(), *function->parameters()[0]->type());
std::string right = expressionAsType(_binOp.rightExpression(), *function->parameters()[1]->type());
solAssert(!left.empty() && !right.empty());
solAssert(_binOp.userDefinedFunctionType()->kind() == FunctionType::Kind::Internal);
@ -853,13 +852,13 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp)
if (auto type = dynamic_cast<IntegerType const*>(commonType))
isSigned = type->isSigned();
string args = expressionAsCleanedType(_binOp.leftExpression(), *commonType);
std::string args = expressionAsCleanedType(_binOp.leftExpression(), *commonType);
args += ", " + expressionAsCleanedType(_binOp.rightExpression(), *commonType);
auto functionType = dynamic_cast<FunctionType const*>(commonType);
solAssert(functionType ? (op == Token::Equal || op == Token::NotEqual) : true, "Invalid function pointer comparison!");
string expr;
std::string expr;
if (functionType && functionType->kind() == FunctionType::Kind::External)
{
@ -879,9 +878,9 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp)
else if (op == Token::NotEqual)
expr = "iszero(eq(" + std::move(args) + "))";
else if (op == Token::GreaterThanOrEqual)
expr = "iszero(" + string(isSigned ? "slt(" : "lt(") + std::move(args) + "))";
expr = "iszero(" + std::string(isSigned ? "slt(" : "lt(") + std::move(args) + "))";
else if (op == Token::LessThanOrEqual)
expr = "iszero(" + string(isSigned ? "sgt(" : "gt(") + std::move(args) + "))";
expr = "iszero(" + std::string(isSigned ? "sgt(" : "gt(") + std::move(args) + "))";
else if (op == Token::GreaterThan)
expr = (isSigned ? "sgt(" : "gt(") + std::move(args) + ")";
else if (op == Token::LessThan)
@ -925,8 +924,8 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp)
}
else
{
string left = expressionAsType(_binOp.leftExpression(), *commonType);
string right = expressionAsType(_binOp.rightExpression(), *commonType);
std::string left = expressionAsType(_binOp.leftExpression(), *commonType);
std::string right = expressionAsType(_binOp.rightExpression(), *commonType);
define(_binOp) << binaryOperation(_binOp.getOperator(), *commonType, left, right) << "\n";
}
return false;
@ -960,7 +959,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
TypePointers parameterTypes = functionType->parameterTypes();
vector<ASTPointer<Expression const>> const& arguments = _functionCall.sortedArguments();
std::vector<ASTPointer<Expression const>> const& arguments = _functionCall.sortedArguments();
if (functionCallKind == FunctionCallKind::StructConstructorCall)
{
@ -1001,7 +1000,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
solAssert(!functionType->takesArbitraryParameters());
vector<string> args;
std::vector<std::string> args;
if (functionType->hasBoundFirstArgument())
args += IRVariable(_functionCall.expression()).part("self").stackSlots();
@ -1049,8 +1048,8 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
TypePointers paramTypes = functionType->parameterTypes();
ABIFunctions abi(m_context.evmVersion(), m_context.revertStrings(), m_context.functionCollector());
vector<IRVariable> indexedArgs;
vector<string> nonIndexedArgs;
std::vector<IRVariable> indexedArgs;
std::vector<std::string> nonIndexedArgs;
TypePointers nonIndexedArgTypes;
TypePointers nonIndexedParamTypes;
if (!event.isAnonymous())
@ -1061,7 +1060,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
Expression const& arg = *arguments[i];
if (event.parameters()[i]->isIndexed())
{
string value;
std::string value;
if (auto const& referenceType = dynamic_cast<ReferenceType const*>(paramTypes[i]))
define(indexedArgs.emplace_back(m_context.newYulVariable(), *TypeProvider::uint256())) <<
m_utils.packedHashFunction({arg.annotation().type}, {referenceType}) <<
@ -1106,7 +1105,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
templ("allocateUnbounded", m_utils.allocateUnboundedFunction());
templ("encode", abi.tupleEncoder(nonIndexedArgTypes, nonIndexedParamTypes));
templ("nonIndexedArgs", joinHumanReadablePrefixed(nonIndexedArgs));
templ("log", "log" + to_string(indexedArgs.size()));
templ("log", "log" + std::to_string(indexedArgs.size()));
templ("indexedArgs", joinHumanReadablePrefixed(indexedArgs | ranges::views::transform([&](auto const& _arg) {
return _arg.commaSeparatedList();
})));
@ -1152,7 +1151,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
arguments.size() > 1 && m_context.revertStrings() != RevertStrings::Strip ?
arguments[1]->annotation().type :
nullptr;
string requireOrAssertFunction = m_utils.requireOrAssertFunction(
std::string requireOrAssertFunction = m_utils.requireOrAssertFunction(
functionType->kind() == FunctionType::Kind::Assert,
messageArgumentType
);
@ -1179,9 +1178,9 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
TypePointers argumentTypes;
TypePointers targetTypes;
vector<string> argumentVars;
string selector;
vector<ASTPointer<Expression const>> argumentsOfEncodeFunction;
std::vector<std::string> argumentVars;
std::string selector;
std::vector<ASTPointer<Expression const>> argumentsOfEncodeFunction;
if (functionType->kind() == FunctionType::Kind::ABIEncodeCall)
{
@ -1252,13 +1251,13 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
// TODO This is an abuse of the `allocateUnbounded` function.
// We might want to introduce a new set of memory handling functions here
// a la "setMemoryCheckPoint" and "freeUntilCheckPoint".
string freeMemoryPre = m_context.newYulVariable();
std::string freeMemoryPre = m_context.newYulVariable();
appendCode() << "let " << freeMemoryPre << " := " << m_utils.allocateUnboundedFunction() << "()\n";
IRVariable array = convert(*arguments[0], *TypeProvider::bytesMemory());
IRVariable hashVariable(m_context.newYulVariable(), *TypeProvider::fixedBytes(32));
string dataAreaFunction = m_utils.arrayDataAreaFunction(*TypeProvider::bytesMemory());
string arrayLengthFunction = m_utils.arrayLengthFunction(*TypeProvider::bytesMemory());
std::string dataAreaFunction = m_utils.arrayDataAreaFunction(*TypeProvider::bytesMemory());
std::string arrayLengthFunction = m_utils.arrayLengthFunction(*TypeProvider::bytesMemory());
define(hashVariable) <<
"keccak256(" <<
(dataAreaFunction + "(" + array.commaSeparatedList() + ")") <<
@ -1389,8 +1388,8 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
{
auto array = convert(*arguments[0], *arrayType);
string dataAreaFunction = m_utils.arrayDataAreaFunction(*arrayType);
string arrayLengthFunction = m_utils.arrayLengthFunction(*arrayType);
std::string dataAreaFunction = m_utils.arrayDataAreaFunction(*arrayType);
std::string arrayLengthFunction = m_utils.arrayLengthFunction(*arrayType);
define(_functionCall) <<
"keccak256(" <<
(dataAreaFunction + "(" + array.commaSeparatedList() + ")") <<
@ -1453,7 +1452,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
case FunctionType::Kind::BytesConcat:
{
TypePointers argumentTypes;
vector<string> argumentVars;
std::vector<std::string> argumentVars;
for (ASTPointer<Expression const> const& argument: arguments)
{
argumentTypes.emplace_back(&type(*argument));
@ -1473,7 +1472,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
case FunctionType::Kind::AddMod:
case FunctionType::Kind::MulMod:
{
static map<FunctionType::Kind, string> functions = {
static std::map<FunctionType::Kind, std::string> functions = {
{FunctionType::Kind::AddMod, "addmod"},
{FunctionType::Kind::MulMod, "mulmod"},
};
@ -1487,7 +1486,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
templ("panic", m_utils.panicFunction(PanicCode::DivisionByZero));
appendCode() << templ.render();
string args;
std::string args;
for (size_t i = 0; i < 2; ++i)
args += expressionAsType(*arguments[i], *(parameterTypes[i])) + ", ";
args += modulus.name();
@ -1498,14 +1497,14 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
case FunctionType::Kind::Selfdestruct:
case FunctionType::Kind::BlockHash:
{
static map<FunctionType::Kind, string> functions = {
static std::map<FunctionType::Kind, std::string> functions = {
{FunctionType::Kind::GasLeft, "gas"},
{FunctionType::Kind::Selfdestruct, "selfdestruct"},
{FunctionType::Kind::BlockHash, "blockhash"},
};
solAssert(functions.find(functionType->kind()) != functions.end());
string args;
std::string args;
for (size_t i = 0; i < arguments.size(); ++i)
args += (args.empty() ? "" : ", ") + expressionAsType(*arguments[i], *(parameterTypes[i]));
define(_functionCall) << functions[functionType->kind()] << "(" << args << ")\n";
@ -1520,7 +1519,7 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
);
TypePointers argumentTypes;
vector<string> constructorParams;
std::vector<std::string> constructorParams;
for (ASTPointer<Expression const> const& arg: arguments)
{
argumentTypes.push_back(arg->annotation().type);
@ -1575,8 +1574,8 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
case FunctionType::Kind::Transfer:
{
solAssert(arguments.size() == 1 && parameterTypes.size() == 1);
string address{IRVariable(_functionCall.expression()).part("address").name()};
string value{expressionAsType(*arguments[0], *(parameterTypes[0]))};
std::string address{IRVariable(_functionCall.expression()).part("address").name()};
std::string value{expressionAsType(*arguments[0], *(parameterTypes[0]))};
Whiskers templ(R"(
let <gas> := 0
if iszero(<value>) { <gas> := <callStipend> }
@ -1608,14 +1607,14 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
solAssert(!functionType->gasSet());
solAssert(!functionType->hasBoundFirstArgument());
static map<FunctionType::Kind, std::tuple<unsigned, size_t>> precompiles = {
static std::map<FunctionType::Kind, std::tuple<unsigned, size_t>> precompiles = {
{FunctionType::Kind::ECRecover, std::make_tuple(1, 0)},
{FunctionType::Kind::SHA256, std::make_tuple(2, 0)},
{FunctionType::Kind::RIPEMD160, std::make_tuple(3, 12)},
};
auto [ address, offset ] = precompiles[functionType->kind()];
TypePointers argumentTypes;
vector<string> argumentStrings;
std::vector<std::string> argumentStrings;
for (auto const& arg: arguments)
{
argumentTypes.emplace_back(&type(*arg));
@ -1676,11 +1675,11 @@ void IRGeneratorForStatements::endVisit(FunctionCallOptions const& _options)
// Copy over existing values.
for (auto const& item: previousType.stackItems())
define(IRVariable(_options).part(get<0>(item)), IRVariable(_options.expression()).part(get<0>(item)));
define(IRVariable(_options).part(std::get<0>(item)), IRVariable(_options.expression()).part(std::get<0>(item)));
for (size_t i = 0; i < _options.names().size(); ++i)
{
string const& name = *_options.names()[i];
std::string const& name = *_options.names()[i];
solAssert(name == "salt" || name == "gas" || name == "value");
define(IRVariable(_options).part(name), *_options.options()[i]);
@ -1785,7 +1784,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
")\n";
else if (member == "code")
{
string externalCodeFunction = m_utils.externalCodeFunction();
std::string externalCodeFunction = m_utils.externalCodeFunction();
define(_memberAccess) <<
externalCodeFunction <<
"(" <<
@ -1797,12 +1796,12 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
"extcodehash(" <<
expressionAsType(_memberAccess.expression(), *TypeProvider::address()) <<
")\n";
else if (set<string>{"send", "transfer"}.count(member))
else if (std::set<std::string>{"send", "transfer"}.count(member))
{
solAssert(dynamic_cast<AddressType const&>(*_memberAccess.expression().annotation().type).stateMutability() == StateMutability::Payable);
define(IRVariable{_memberAccess}.part("address"), _memberAccess.expression());
}
else if (set<string>{"call", "callcode", "delegatecall", "staticcall"}.count(member))
else if (std::set<std::string>{"call", "callcode", "delegatecall", "staticcall"}.count(member))
define(IRVariable{_memberAccess}.part("address"), _memberAccess.expression());
else
solAssert(false, "Invalid member access to address");
@ -1945,7 +1944,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
{
MagicType const* arg = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type);
string requestedValue;
std::string requestedValue;
if (IntegerType const* integerType = dynamic_cast<IntegerType const*>(arg->typeArgument()))
{
if (member == "min")
@ -1956,16 +1955,16 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
else if (EnumType const* enumType = dynamic_cast<EnumType const*>(arg->typeArgument()))
{
if (member == "min")
requestedValue = to_string(enumType->minValue());
requestedValue = std::to_string(enumType->minValue());
else
requestedValue = to_string(enumType->maxValue());
requestedValue = std::to_string(enumType->maxValue());
}
else
solAssert(false, "min/max requested on unexpected type.");
define(_memberAccess) << requestedValue << "\n";
}
else if (set<string>{"encode", "encodePacked", "encodeWithSelector", "encodeCall", "encodeWithSignature", "decode"}.count(member))
else if (std::set<std::string>{"encode", "encodePacked", "encodeWithSelector", "encodeCall", "encodeWithSignature", "decode"}.count(member))
{
// no-op
}
@ -1981,8 +1980,8 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
{
case DataLocation::Storage:
{
pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member);
string slot = m_context.newYulVariable();
std::pair<u256, unsigned> const& offsets = structType.storageOffsetsOfMember(member);
std::string slot = m_context.newYulVariable();
appendCode() << "let " << slot << " := " <<
("add(" + expression.part("slot").name() + ", " + offsets.first.str() + ")\n");
setLValue(_memberAccess, IRLValue{
@ -1993,7 +1992,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
}
case DataLocation::Memory:
{
string pos = m_context.newYulVariable();
std::string pos = m_context.newYulVariable();
appendCode() << "let " << pos << " := " <<
("add(" + expression.part("mpos").name() + ", " + structType.memoryOffsetOfMember(member).str() + ")\n");
setLValue(_memberAccess, IRLValue{
@ -2004,9 +2003,9 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
}
case DataLocation::CallData:
{
string baseRef = expression.part("offset").name();
string offset = m_context.newYulVariable();
appendCode() << "let " << offset << " := " << "add(" << baseRef << ", " << to_string(structType.calldataOffsetOfMember(member)) << ")\n";
std::string baseRef = expression.part("offset").name();
std::string offset = m_context.newYulVariable();
appendCode() << "let " << offset << " := " << "add(" << baseRef << ", " << std::to_string(structType.calldataOffsetOfMember(member)) << ")\n";
if (_memberAccess.annotation().type->isDynamicallyEncoded())
define(_memberAccess) <<
m_utils.accessCalldataTailFunction(*_memberAccess.annotation().type) <<
@ -2036,7 +2035,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
case Type::Category::Enum:
{
EnumType const& type = dynamic_cast<EnumType const&>(*_memberAccess.expression().annotation().type);
define(_memberAccess) << to_string(type.memberValue(_memberAccess.memberName())) << "\n";
define(_memberAccess) << std::to_string(type.memberValue(_memberAccess.memberName())) << "\n";
break;
}
case Type::Category::Array:
@ -2076,7 +2075,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
{
auto const& type = dynamic_cast<FixedBytesType const&>(*_memberAccess.expression().annotation().type);
if (member == "length")
define(_memberAccess) << to_string(type.numBytes()) << "\n";
define(_memberAccess) << std::to_string(type.numBytes()) << "\n";
else
solAssert(false, "Illegal fixed bytes member.");
break;
@ -2162,7 +2161,7 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
solAssert(false);
}
else if (EnumType const* enumType = dynamic_cast<EnumType const*>(&actualType))
define(_memberAccess) << to_string(enumType->memberValue(_memberAccess.memberName())) << "\n";
define(_memberAccess) << std::to_string(enumType->memberValue(_memberAccess.memberName())) << "\n";
else if (dynamic_cast<UserDefinedValueType const*>(&actualType))
solAssert(member == "wrap" || member == "unwrap");
else if (auto const* arrayType = dynamic_cast<ArrayType const*>(&actualType))
@ -2222,7 +2221,7 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)
yul::Statement modified = bodyCopier(_inlineAsm.operations());
solAssert(holds_alternative<yul::Block>(modified));
solAssert(std::holds_alternative<yul::Block>(modified));
// Do not provide dialect so that we get the full type information.
appendCode() << yul::AsmPrinter()(std::get<yul::Block>(modified)) << "\n";
@ -2242,7 +2241,7 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
MappingType const& mappingType = dynamic_cast<MappingType const&>(baseType);
Type const& keyType = *_indexAccess.indexExpression()->annotation().type;
string slot = m_context.newYulVariable();
std::string slot = m_context.newYulVariable();
Whiskers templ("let <slot> := <indexAccess>(<base><?+key>,<key></+key>)\n");
templ("slot", slot);
templ("indexAccess", m_utils.mappingIndexAccessFunction(mappingType, keyType));
@ -2273,8 +2272,8 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
{
case DataLocation::Storage:
{
string slot = m_context.newYulVariable();
string offset = m_context.newYulVariable();
std::string slot = m_context.newYulVariable();
std::string offset = m_context.newYulVariable();
appendCode() << Whiskers(R"(
let <slot>, <offset> := <indexFunc>(<array>, <index>)
@ -2295,13 +2294,13 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
}
case DataLocation::Memory:
{
string const indexAccessFunction = m_utils.memoryArrayIndexAccessFunction(arrayType);
string const baseRef = IRVariable(_indexAccess.baseExpression()).part("mpos").name();
string const indexExpression = expressionAsType(
std::string const indexAccessFunction = m_utils.memoryArrayIndexAccessFunction(arrayType);
std::string const baseRef = IRVariable(_indexAccess.baseExpression()).part("mpos").name();
std::string const indexExpression = expressionAsType(
*_indexAccess.indexExpression(),
*TypeProvider::uint256()
);
string const memAddress = indexAccessFunction + "(" + baseRef + ", " + indexExpression + ")";
std::string const memAddress = indexAccessFunction + "(" + baseRef + ", " + indexExpression + ")";
setLValue(_indexAccess, IRLValue{
*arrayType.baseType(),
@ -2311,13 +2310,13 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
}
case DataLocation::CallData:
{
string const indexAccessFunction = m_utils.calldataArrayIndexAccessFunction(arrayType);
string const baseRef = IRVariable(_indexAccess.baseExpression()).commaSeparatedList();
string const indexExpression = expressionAsType(
std::string const indexAccessFunction = m_utils.calldataArrayIndexAccessFunction(arrayType);
std::string const baseRef = IRVariable(_indexAccess.baseExpression()).commaSeparatedList();
std::string const indexExpression = expressionAsType(
*_indexAccess.indexExpression(),
*TypeProvider::uint256()
);
string const calldataAddress = indexAccessFunction + "(" + baseRef + ", " + indexExpression + ")";
std::string const calldataAddress = indexAccessFunction + "(" + baseRef + ", " + indexExpression + ")";
if (arrayType.isByteArrayOrString())
define(_indexAccess) <<
@ -2349,7 +2348,7 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
let <result> := <shl248>(byte(<index>, <array>))
)")
("index", index.name())
("length", to_string(fixedBytesType.numBytes()))
("length", std::to_string(fixedBytesType.numBytes()))
("panic", m_utils.panicFunction(PanicCode::ArrayOutOfBounds))
("array", IRVariable(_indexAccess.baseExpression()).name())
("shl248", m_utils.shiftLeftFunction(256 - 8))
@ -2538,7 +2537,7 @@ void IRGeneratorForStatements::handleVariableReference(
void IRGeneratorForStatements::appendExternalFunctionCall(
FunctionCall const& _functionCall,
vector<ASTPointer<Expression const>> const& _arguments
std::vector<ASTPointer<Expression const>> const& _arguments
)
{
FunctionType const& funType = dynamic_cast<FunctionType const&>(type(_functionCall.expression()));
@ -2559,7 +2558,7 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
TypePointers parameterTypes = funType.parameterTypes();
TypePointers argumentTypes;
vector<string> argumentStrings;
std::vector<std::string> argumentStrings;
if (funType.hasBoundFirstArgument())
{
parameterTypes.insert(parameterTypes.begin(), funType.selfType());
@ -2581,7 +2580,7 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
// We could also just use MLOAD; POP right before the gas calculation, but the optimizer
// would remove that, so we use MSTORE here.
if (!funType.gasSet() && returnInfo.estimatedReturnSize > 0)
appendCode() << "mstore(add(" << m_utils.allocateUnboundedFunction() << "() , " << to_string(returnInfo.estimatedReturnSize) << "), 0)\n";
appendCode() << "mstore(add(" << m_utils.allocateUnboundedFunction() << "() , " << std::to_string(returnInfo.estimatedReturnSize) << "), 0)\n";
}
// NOTE: When the expected size of returndata is static, we pass that in to the call opcode and it gets copied automatically.
@ -2649,10 +2648,10 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
if (returnInfo.dynamicReturnSize)
solAssert(m_context.evmVersion().supportsReturndata());
templ("returnDataSizeVar", m_context.newYulVariable());
templ("staticReturndataSize", to_string(returnInfo.estimatedReturnSize));
templ("staticReturndataSize", std::to_string(returnInfo.estimatedReturnSize));
templ("supportsReturnData", m_context.evmVersion().supportsReturndata());
string const retVars = IRVariable(_functionCall).commaSeparatedList();
std::string const retVars = IRVariable(_functionCall).commaSeparatedList();
templ("retVars", retVars);
solAssert(retVars.empty() == returnInfo.returnTypes.empty());
@ -2704,7 +2703,7 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
void IRGeneratorForStatements::appendBareCall(
FunctionCall const& _functionCall,
vector<ASTPointer<Expression const>> const& _arguments
std::vector<ASTPointer<Expression const>> const& _arguments
)
{
FunctionType const& funType = dynamic_cast<FunctionType const&>(type(_functionCall.expression()));
@ -2807,7 +2806,7 @@ void IRGeneratorForStatements::assignInternalFunctionIDIfNotCalledDirectly(
return;
define(IRVariable(_expression).part("functionIdentifier")) <<
to_string(m_context.mostDerivedContract().annotation().internalFunctionIDs.at(&_referencedFunction)) <<
std::to_string(m_context.mostDerivedContract().annotation().internalFunctionIDs.at(&_referencedFunction)) <<
"\n";
m_context.addToInternalDispatch(_referencedFunction);
}
@ -2864,7 +2863,7 @@ void IRGeneratorForStatements::declare(IRVariable const& _var)
void IRGeneratorForStatements::declareAssign(IRVariable const& _lhs, IRVariable const& _rhs, bool _declare, bool _forceCleanup)
{
string output;
std::string output;
if (_lhs.type() == _rhs.type() && !_forceCleanup)
for (auto const& [stackItemName, stackItemType]: _lhs.type().stackItems())
if (stackItemType)
@ -2894,7 +2893,7 @@ IRVariable IRGeneratorForStatements::zeroValue(Type const& _type, bool _splitFun
void IRGeneratorForStatements::appendSimpleUnaryOperation(UnaryOperation const& _operation, Expression const& _expr)
{
string func;
std::string func;
if (_operation.getOperator() == Token::Not)
func = "iszero";
@ -2913,18 +2912,18 @@ void IRGeneratorForStatements::appendSimpleUnaryOperation(UnaryOperation const&
")\n";
}
string IRGeneratorForStatements::binaryOperation(
std::string IRGeneratorForStatements::binaryOperation(
langutil::Token _operator,
Type const& _type,
string const& _left,
string const& _right
std::string const& _left,
std::string const& _right
)
{
solAssert(
!TokenTraits::isShiftOp(_operator),
"Have to use specific shift operation function for shifts."
);
string fun;
std::string fun;
if (TokenTraits::isBitOp(_operator))
{
solAssert(
@ -3030,12 +3029,12 @@ void IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable
std::visit(
util::GenericVisitor{
[&](IRLValue::Storage const& _storage) {
string offsetArgument;
optional<unsigned> offsetStatic;
std::string offsetArgument;
std::optional<unsigned> offsetStatic;
std::visit(GenericVisitor{
[&](unsigned _offset) { offsetStatic = _offset; },
[&](string const& _offset) { offsetArgument = ", " + _offset; }
[&](std::string const& _offset) { offsetArgument = ", " + _offset; }
}, _storage.offset);
appendCode() <<
@ -3068,7 +3067,7 @@ void IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable
}
else if (auto const* literalType = dynamic_cast<StringLiteralType const*>(&_value.type()))
{
string writeUInt = m_utils.writeToMemoryFunction(*TypeProvider::uint256());
std::string writeUInt = m_utils.writeToMemoryFunction(*TypeProvider::uint256());
appendCode() <<
writeUInt <<
"(" <<
@ -3099,7 +3098,7 @@ void IRGeneratorForStatements::writeToLValue(IRLValue const& _lvalue, IRVariable
IRVariable prepared(m_context.newYulVariable(), _lvalue.type);
define(prepared, _value);
appendCode() << "mstore(" << to_string(memOffset) << ", " << prepared.commaSeparatedList() << ")\n";
appendCode() << "mstore(" << std::to_string(memOffset) << ", " << prepared.commaSeparatedList() << ")\n";
},
[&](IRLValue::Tuple const& _tuple) {
auto components = std::move(_tuple.components);
@ -3122,13 +3121,13 @@ IRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue)
[&](IRLValue::Storage const& _storage) {
if (!_lvalue.type.isValueType())
define(result) << _storage.slot << "\n";
else if (std::holds_alternative<string>(_storage.offset))
else if (std::holds_alternative<std::string>(_storage.offset))
define(result) <<
m_utils.readFromStorageDynamic(_lvalue.type, true) <<
"(" <<
_storage.slot <<
", " <<
std::get<string>(_storage.offset) <<
std::get<std::string>(_storage.offset) <<
")\n";
else
define(result) <<
@ -3156,15 +3155,15 @@ IRVariable IRGeneratorForStatements::readFromLValue(IRLValue const& _lvalue)
solAssert(_lvalue.type == *_immutable.variable->type());
if (m_context.executionContext() == IRGenerationContext::ExecutionContext::Creation)
{
string readFunction = m_utils.readFromMemory(*_immutable.variable->type());
std::string readFunction = m_utils.readFromMemory(*_immutable.variable->type());
define(result) <<
readFunction <<
"(" <<
to_string(m_context.immutableMemoryOffset(*_immutable.variable)) <<
std::to_string(m_context.immutableMemoryOffset(*_immutable.variable)) <<
")\n";
}
else
define(result) << "loadimmutable(\"" << to_string(_immutable.variable->id()) << "\")\n";
define(result) << "loadimmutable(\"" << std::to_string(_immutable.variable->id()) << "\")\n";
},
[&](IRLValue::Tuple const&) {
solAssert(false, "Attempted to read from tuple lvalue.");
@ -3181,7 +3180,7 @@ void IRGeneratorForStatements::setLValue(Expression const& _expression, IRLValue
{
m_currentLValue.emplace(std::move(_lvalue));
if (_lvalue.type.dataStoredIn(DataLocation::CallData))
solAssert(holds_alternative<IRLValue::Stack>(_lvalue.kind));
solAssert(std::holds_alternative<IRLValue::Stack>(_lvalue.kind));
}
else
// Only define the expression, if it will not be written to.
@ -3196,7 +3195,7 @@ void IRGeneratorForStatements::generateLoop(
bool _isDoWhile
)
{
string firstRun;
std::string firstRun;
if (_isDoWhile)
{
@ -3278,7 +3277,7 @@ bool IRGeneratorForStatements::visit(TryStatement const& _tryStatement)
void IRGeneratorForStatements::handleCatch(TryStatement const& _tryStatement)
{
setLocation(_tryStatement);
string const runFallback = m_context.newYulVariable();
std::string const runFallback = m_context.newYulVariable();
appendCode() << "let " << runFallback << " := 1\n";
// This function returns zero on "short returndata". We have to add a success flag
@ -3290,7 +3289,7 @@ void IRGeneratorForStatements::handleCatch(TryStatement const& _tryStatement)
{
appendCode() << "case " << selectorFromSignatureU32("Error(string)") << " {\n";
setLocation(*errorClause);
string const dataVariable = m_context.newYulVariable();
std::string const dataVariable = m_context.newYulVariable();
appendCode() << "let " << dataVariable << " := " << m_utils.tryDecodeErrorMessageFunction() << "()\n";
appendCode() << "if " << dataVariable << " {\n";
appendCode() << runFallback << " := 0\n";
@ -3310,8 +3309,8 @@ void IRGeneratorForStatements::handleCatch(TryStatement const& _tryStatement)
{
appendCode() << "case " << selectorFromSignatureU32("Panic(uint256)") << " {\n";
setLocation(*panicClause);
string const success = m_context.newYulVariable();
string const code = m_context.newYulVariable();
std::string const success = m_context.newYulVariable();
std::string const code = m_context.newYulVariable();
appendCode() << "let " << success << ", " << code << " := " << m_utils.tryDecodePanicDataFunction() << "()\n";
appendCode() << "if " << success << " {\n";
appendCode() << runFallback << " := 0\n";
@ -3358,9 +3357,9 @@ void IRGeneratorForStatements::handleCatchFallback(TryCatchClause const& _fallba
}
void IRGeneratorForStatements::revertWithError(
string const& _signature,
vector<Type const*> const& _parameterTypes,
vector<ASTPointer<Expression const>> const& _errorArguments
std::string const& _signature,
std::vector<Type const*> const& _parameterTypes,
std::vector<ASTPointer<Expression const>> const& _errorArguments
)
{
Whiskers templ(R"({
@ -3374,8 +3373,8 @@ void IRGeneratorForStatements::revertWithError(
templ("hash", util::selectorFromSignatureU256(_signature).str());
templ("allocateUnbounded", m_utils.allocateUnboundedFunction());
vector<string> errorArgumentVars;
vector<Type const*> errorArgumentTypes;
std::vector<std::string> errorArgumentVars;
std::vector<Type const*> errorArgumentTypes;
for (ASTPointer<Expression const> const& arg: _errorArguments)
{
errorArgumentVars += IRVariable(*arg).stackSlots();
@ -3395,7 +3394,7 @@ bool IRGeneratorForStatements::visit(TryCatchClause const& _clause)
return false;
}
string IRGeneratorForStatements::linkerSymbol(ContractDefinition const& _library) const
std::string IRGeneratorForStatements::linkerSymbol(ContractDefinition const& _library) const
{
solAssert(_library.isLibrary());
return "linkersymbol(" + util::escapeAndQuoteString(_library.fullyQualifiedName()) + ")";

View File

@ -20,7 +20,6 @@
#include <libsolidity/ast/AST.h>
#include <libsolutil/StringUtils.h>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
using namespace solidity::util;
@ -41,7 +40,7 @@ IRVariable::IRVariable(Expression const& _expression):
{
}
IRVariable IRVariable::part(string const& _name) const
IRVariable IRVariable::part(std::string const& _name) const
{
for (auto const& [itemName, itemType]: m_type.stackItems())
if (itemName == _name)
@ -63,9 +62,9 @@ bool IRVariable::hasPart(std::string const& _name) const
return false;
}
vector<string> IRVariable::stackSlots() const
std::vector<std::string> IRVariable::stackSlots() const
{
vector<string> result;
std::vector<std::string> result;
for (auto const& [itemName, itemType]: m_type.stackItems())
if (itemType)
{
@ -81,17 +80,17 @@ vector<string> IRVariable::stackSlots() const
return result;
}
string IRVariable::commaSeparatedList() const
std::string IRVariable::commaSeparatedList() const
{
return joinHumanReadable(stackSlots());
}
string IRVariable::commaSeparatedListPrefixed() const
std::string IRVariable::commaSeparatedListPrefixed() const
{
return joinHumanReadablePrefixed(stackSlots());
}
string IRVariable::name() const
std::string IRVariable::name() const
{
solAssert(m_type.sizeOnStack() == 1, "");
auto const& [itemName, type] = m_type.stackItems().front();
@ -108,7 +107,7 @@ IRVariable IRVariable::tupleComponent(size_t _i) const
return part(IRNames::tupleComponent(_i));
}
string IRVariable::suffixedName(string const& _suffix) const
std::string IRVariable::suffixedName(std::string const& _suffix) const
{
if (_suffix.empty())
return m_baseName;

View File

@ -0,0 +1,34 @@
/*
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
#include <libsolidity/experimental/analysis/Analysis.h>
#include <liblangutil/ErrorReporter.h>
using namespace solidity::langutil;
using namespace solidity::frontend::experimental;
bool Analysis::check(std::vector<std::shared_ptr<SourceUnit const>> const&)
{
m_errorReporter.error(
6547_error,
Error::Type::UnimplementedFeatureError,
SourceLocation{},
"Experimental Analysis is not implemented yet."
);
return false;
}

View File

@ -15,33 +15,35 @@
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
/**
* Changes the topmost block to be a function with a specific name ("main") which has no
* inputs nor outputs.
*/
#pragma once
#include <libyul/ASTForward.h>
#include <vector>
#include <memory>
namespace solidity::yul
namespace solidity::frontend
{
class SourceUnit;
}
namespace solidity::langutil
{
class ErrorReporter;
}
namespace solidity::frontend::experimental
{
struct OptimiserStepContext;
/**
* Prerequisites: Function Grouper
*/
class MainFunction
class Analysis
{
public:
static constexpr char const* name{"MainFunction"};
static void run(OptimiserStepContext&, Block& _ast) { MainFunction{}(_ast); }
Analysis(langutil::ErrorReporter& _errorReporter):
m_errorReporter(_errorReporter)
{}
void operator()(Block& _block);
bool check(std::vector<std::shared_ptr<SourceUnit const>> const& _sourceUnits);
private:
MainFunction() = default;
langutil::ErrorReporter& m_errorReporter;
};
}

View File

@ -20,18 +20,17 @@
#include <liblangutil/Exceptions.h>
using namespace std;
using namespace solidity;
using namespace solidity::smtutil;
using namespace solidity::frontend;
using namespace solidity::frontend::smt;
map<string, ArraySlicePredicate::SliceData> ArraySlicePredicate::m_slicePredicates;
std::map<std::string, ArraySlicePredicate::SliceData> ArraySlicePredicate::m_slicePredicates;
pair<bool, ArraySlicePredicate::SliceData const&> ArraySlicePredicate::create(SortPointer _sort, EncodingContext& _context)
std::pair<bool, ArraySlicePredicate::SliceData const&> ArraySlicePredicate::create(SortPointer _sort, EncodingContext& _context)
{
solAssert(_sort->kind == Kind::Tuple, "");
auto tupleSort = dynamic_pointer_cast<TupleSort>(_sort);
auto tupleSort = std::dynamic_pointer_cast<TupleSort>(_sort);
solAssert(tupleSort, "");
auto tupleName = tupleSort->name;
@ -47,12 +46,12 @@ pair<bool, ArraySlicePredicate::SliceData const&> ArraySlicePredicate::create(So
smt::SymbolicIntVariable endVar{TypeProvider::uint256(), TypeProvider::uint256(), "end_" + tupleName, _context };
smt::SymbolicIntVariable iVar{TypeProvider::uint256(), TypeProvider::uint256(), "i_" + tupleName, _context};
vector<SortPointer> domain{sort, sort, startVar.sort(), endVar.sort()};
auto sliceSort = make_shared<FunctionSort>(domain, SortProvider::boolSort);
std::vector<SortPointer> domain{sort, sort, startVar.sort(), endVar.sort()};
auto sliceSort = std::make_shared<FunctionSort>(domain, SortProvider::boolSort);
Predicate const& slice = *Predicate::create(sliceSort, "array_slice_" + tupleName, PredicateType::Custom, _context);
domain.emplace_back(iVar.sort());
auto predSort = make_shared<FunctionSort>(domain, SortProvider::boolSort);
auto predSort = std::make_shared<FunctionSort>(domain, SortProvider::boolSort);
Predicate const& header = *Predicate::create(predSort, "array_slice_header_" + tupleName, PredicateType::Custom, _context);
Predicate const& loop = *Predicate::create(predSort, "array_slice_loop_" + tupleName, PredicateType::Custom, _context);

View File

@ -31,7 +31,6 @@
#include <z3_version.h>
#endif
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::langutil;
@ -41,13 +40,13 @@ BMC::BMC(
smt::EncodingContext& _context,
UniqueErrorReporter& _errorReporter,
UniqueErrorReporter& _unsupportedErrorReporter,
map<h256, string> const& _smtlib2Responses,
std::map<h256, std::string> const& _smtlib2Responses,
ReadCallback::Callback const& _smtCallback,
ModelCheckerSettings _settings,
CharStreamProvider const& _charStreamProvider
):
SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _charStreamProvider),
m_interface(make_unique<smtutil::SMTPortfolio>(
m_interface(std::make_unique<smtutil::SMTPortfolio>(
_smtlib2Responses, _smtCallback, _settings.solvers, _settings.timeout, _settings.printQuery
))
{
@ -65,7 +64,7 @@ BMC::BMC(
#endif
}
void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<VerificationTargetType>, smt::EncodingContext::IdCompare> _solvedTargets)
void BMC::analyze(SourceUnit const& _source, std::map<ASTNode const*, std::set<VerificationTargetType>, smt::EncodingContext::IdCompare> _solvedTargets)
{
// At this point every enabled solver is available.
if (!m_settings.solvers.cvc4 && !m_settings.solvers.smtlib2 && !m_settings.solvers.z3)
@ -97,7 +96,7 @@ void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<Verificatio
2788_error,
{},
"BMC: " +
to_string(m_unprovedAmt) +
std::to_string(m_unprovedAmt) +
" verification condition(s) could not be proved." +
" Enable the model checker option \"show unproved\" to see all of them." +
" Consider choosing a specific contract to be verified in order to reduce the solving problems." +
@ -108,7 +107,7 @@ void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<Verificatio
m_errorReporter.info(
6002_error,
"BMC: " +
to_string(m_safeTargets.size()) +
std::to_string(m_safeTargets.size()) +
" verification condition(s) proved safe!" +
" Enable the model checker option \"show proved safe\" to see all of them."
);
@ -138,7 +137,7 @@ void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<Verificatio
"BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available."
" None of the installed solvers was enabled."
#ifdef HAVE_Z3_DLOPEN
" Install libz3.so." + to_string(Z3_MAJOR_VERSION) + "." + to_string(Z3_MINOR_VERSION) + " to enable Z3."
" Install libz3.so." + std::to_string(Z3_MAJOR_VERSION) + "." + std::to_string(Z3_MINOR_VERSION) + " to enable Z3."
#endif
);
}
@ -504,11 +503,11 @@ bool BMC::visit(TryStatement const& _tryStatement)
if (_tryStatement.successClause()->parameters())
expressionToTupleAssignment(_tryStatement.successClause()->parameters()->parameters(), *externalCall);
smtutil::Expression clauseId = m_context.newVariable("clause_choice_" + to_string(m_context.newUniqueId()), smtutil::SortProvider::uintSort);
smtutil::Expression clauseId = m_context.newVariable("clause_choice_" + std::to_string(m_context.newUniqueId()), smtutil::SortProvider::uintSort);
auto const& clauses = _tryStatement.clauses();
m_context.addAssertion(clauseId >= 0 && clauseId < clauses.size());
solAssert(clauses[0].get() == _tryStatement.successClause(), "First clause of TryStatement should be the success clause");
vector<pair<VariableIndices, smtutil::Expression>> clausesVisitResults;
std::vector<std::pair<VariableIndices, smtutil::Expression>> clausesVisitResults;
for (size_t i = 0; i < clauses.size(); ++i)
clausesVisitResults.push_back(visitBranch(clauses[i].get()));
@ -736,7 +735,7 @@ void BMC::internalOrExternalFunctionCall(FunctionCall const& _funCall)
}
}
pair<smtutil::Expression, smtutil::Expression> BMC::arithmeticOperation(
std::pair<smtutil::Expression, smtutil::Expression> BMC::arithmeticOperation(
Token _op,
smtutil::Expression const& _left,
smtutil::Expression const& _right,
@ -800,10 +799,10 @@ void BMC::reset()
m_loopExecutionHappened = false;
}
pair<vector<smtutil::Expression>, vector<string>> BMC::modelExpressions()
std::pair<std::vector<smtutil::Expression>, std::vector<std::string>> BMC::modelExpressions()
{
vector<smtutil::Expression> expressionsToEvaluate;
vector<string> expressionNames;
std::vector<smtutil::Expression> expressionsToEvaluate;
std::vector<std::string> expressionNames;
for (auto const& var: m_context.variables())
if (var.first->type()->isValueType())
{
@ -826,7 +825,7 @@ pair<vector<smtutil::Expression>, vector<string>> BMC::modelExpressions()
if (uf->annotation().type->isValueType())
{
expressionsToEvaluate.emplace_back(expr(*uf));
string expressionName;
std::string expressionName;
if (uf->location().hasText())
expressionName = m_charStreamProvider.charStream(*uf->location().sourceName).text(
uf->location()
@ -839,7 +838,7 @@ pair<vector<smtutil::Expression>, vector<string>> BMC::modelExpressions()
/// Verification targets.
string BMC::targetDescription(BMCVerificationTarget const& _target)
std::string BMC::targetDescription(BMCVerificationTarget const& _target)
{
if (
_target.type == VerificationTargetType::Underflow ||
@ -1065,20 +1064,20 @@ void BMC::addVerificationTarget(
void BMC::checkCondition(
BMCVerificationTarget const& _target,
smtutil::Expression _condition,
vector<SMTEncoder::CallStackEntry> const& _callStack,
pair<vector<smtutil::Expression>, vector<string>> const& _modelExpressions,
std::vector<SMTEncoder::CallStackEntry> const& _callStack,
std::pair<std::vector<smtutil::Expression>, std::vector<std::string>> const& _modelExpressions,
SourceLocation const& _location,
ErrorId _errorHappens,
ErrorId _errorMightHappen,
string const& _additionalValueName,
std::string const& _additionalValueName,
smtutil::Expression const* _additionalValue
)
{
m_interface->push();
m_interface->addAssertion(_condition);
vector<smtutil::Expression> expressionsToEvaluate;
vector<string> expressionNames;
std::vector<smtutil::Expression> expressionsToEvaluate;
std::vector<std::string> expressionNames;
tie(expressionsToEvaluate, expressionNames) = _modelExpressions;
if (!_callStack.empty())
if (_additionalValue)
@ -1087,10 +1086,10 @@ void BMC::checkCondition(
expressionNames.push_back(_additionalValueName);
}
smtutil::CheckResult result;
vector<string> values;
std::vector<std::string> values;
tie(result, values) = checkSatisfiableAndGenerateModel(expressionsToEvaluate);
string extraComment = SMTEncoder::extraComment();
std::string extraComment = SMTEncoder::extraComment();
if (m_loopExecutionHappened)
extraComment +=
"False negatives are possible when unrolling loops.\n"
@ -1119,7 +1118,7 @@ void BMC::checkCondition(
if (values.size() == expressionNames.size())
{
modelMessage << "Counterexample:\n";
map<string, string> sortedModel;
std::map<std::string, std::string> sortedModel;
for (size_t i = 0; i < values.size(); ++i)
if (expressionsToEvaluate.at(i).name != values.at(i))
sortedModel[expressionNames.at(i)] = values.at(i);
@ -1165,7 +1164,7 @@ void BMC::checkBooleanNotConstant(
Expression const& _condition,
smtutil::Expression const& _constraints,
smtutil::Expression const& _value,
vector<SMTEncoder::CallStackEntry> const& _callStack
std::vector<SMTEncoder::CallStackEntry> const& _callStack
)
{
// Do not check for const-ness if this is a constant.
@ -1198,7 +1197,7 @@ void BMC::checkBooleanNotConstant(
m_errorReporter.warning(2512_error, _condition.location(), "BMC: Condition unreachable.", SMTEncoder::callStackMessage(_callStack));
else
{
string description;
std::string description;
if (positiveResult == smtutil::CheckResult::SATISFIABLE)
{
solAssert(negatedResult == smtutil::CheckResult::UNSATISFIABLE, "");
@ -1219,17 +1218,17 @@ void BMC::checkBooleanNotConstant(
}
}
pair<smtutil::CheckResult, vector<string>>
BMC::checkSatisfiableAndGenerateModel(vector<smtutil::Expression> const& _expressionsToEvaluate)
std::pair<smtutil::CheckResult, std::vector<std::string>>
BMC::checkSatisfiableAndGenerateModel(std::vector<smtutil::Expression> const& _expressionsToEvaluate)
{
smtutil::CheckResult result;
vector<string> values;
std::vector<std::string> values;
try
{
if (m_settings.printQuery)
{
auto portfolio = dynamic_cast<smtutil::SMTPortfolio*>(m_interface.get());
string smtlibCode = portfolio->dumpQuery(_expressionsToEvaluate);
std::string smtlibCode = portfolio->dumpQuery(_expressionsToEvaluate);
m_errorReporter.info(
6240_error,
"BMC: Requested query:\n" + smtlibCode
@ -1239,14 +1238,14 @@ BMC::checkSatisfiableAndGenerateModel(vector<smtutil::Expression> const& _expres
}
catch (smtutil::SolverError const& _e)
{
string description("BMC: Error querying SMT solver");
std::string description("BMC: Error querying SMT solver");
if (_e.comment())
description += ": " + *_e.comment();
m_errorReporter.warning(8140_error, description);
result = smtutil::CheckResult::ERROR;
}
for (string& value: values)
for (std::string& value: values)
{
try
{

View File

@ -51,7 +51,6 @@
#include <charconv>
#include <queue>
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::langutil;
@ -63,7 +62,7 @@ CHC::CHC(
EncodingContext& _context,
UniqueErrorReporter& _errorReporter,
UniqueErrorReporter& _unsupportedErrorReporter,
map<util::h256, string> const& _smtlib2Responses,
std::map<util::h256, std::string> const& _smtlib2Responses,
ReadCallback::Callback const& _smtCallback,
ModelCheckerSettings _settings,
CharStreamProvider const& _charStreamProvider
@ -130,7 +129,7 @@ void CHC::analyze(SourceUnit const& _source)
);
}
vector<string> CHC::unhandledQueries() const
std::vector<std::string> CHC::unhandledQueries() const
{
if (auto smtlib2 = dynamic_cast<CHCSmtLib2Interface const*>(m_interface.get()))
return smtlib2->unhandledQueries();
@ -213,7 +212,7 @@ void CHC::endVisit(ContractDefinition const& _contract)
auto baseConstructor = base->constructor();
if (baseConstructor && baseArgs.count(base))
{
vector<ASTPointer<Expression>> const& args = baseArgs.at(base);
std::vector<ASTPointer<Expression>> const& args = baseArgs.at(base);
auto const& params = baseConstructor->parameters();
solAssert(params.size() == args.size(), "");
for (unsigned i = 0; i < params.size(); ++i)
@ -280,7 +279,7 @@ bool CHC::visit(FunctionDefinition const& _function)
conj = conj && currentEqualInitialVarsConstraints(stateVariablesIncludingInheritedAndPrivate(_function));
conj = conj && errorFlag().currentValue() == 0;
addRule(smtutil::Expression::implies(conj, summary(_function)), "summary_function_" + to_string(_function.id()));
addRule(smtutil::Expression::implies(conj, summary(_function)), "summary_function_" + std::to_string(_function.id()));
return false;
}
@ -433,7 +432,7 @@ bool CHC::visit(WhileStatement const& _while)
solAssert(m_currentFunction, "");
auto const& functionBody = m_currentFunction->body();
auto namePrefix = string(_while.isDoWhile() ? "do_" : "") + "while";
auto namePrefix = std::string(_while.isDoWhile() ? "do_" : "") + "while";
auto loopHeaderBlock = createBlock(&_while, PredicateType::FunctionBlock, namePrefix + "_header_");
auto loopBodyBlock = createBlock(&_while.body(), PredicateType::FunctionBlock, namePrefix + "_body_");
auto afterLoopBlock = createBlock(&functionBody, PredicateType::FunctionBlock);
@ -622,8 +621,8 @@ void CHC::endVisit(IndexRangeAccess const& _range)
{
createExpr(_range);
auto baseArray = dynamic_pointer_cast<SymbolicArrayVariable>(m_context.expression(_range.baseExpression()));
auto sliceArray = dynamic_pointer_cast<SymbolicArrayVariable>(m_context.expression(_range));
auto baseArray = std::dynamic_pointer_cast<SymbolicArrayVariable>(m_context.expression(_range.baseExpression()));
auto sliceArray = std::dynamic_pointer_cast<SymbolicArrayVariable>(m_context.expression(_range));
solAssert(baseArray && sliceArray, "");
auto const& sliceData = ArraySlicePredicate::create(sliceArray->sort(), m_context);
@ -864,7 +863,7 @@ void CHC::nondetCall(ContractDefinition const& _contract, VariableDeclaration co
state().readStateVars(_contract, address);
m_context.addAssertion(state().state() == state().state(0));
auto preCallState = vector<smtutil::Expression>{state().state()} + currentStateVariables(_contract);
auto preCallState = std::vector<smtutil::Expression>{state().state()} + currentStateVariables(_contract);
state().newState();
for (auto const* var: _contract.stateVariables())
@ -879,8 +878,8 @@ void CHC::nondetCall(ContractDefinition const& _contract, VariableDeclaration co
&_var,
m_currentContract
);
auto postCallState = vector<smtutil::Expression>{state().state()} + currentStateVariables(_contract);
vector<smtutil::Expression> stateExprs{error, address, state().abi(), state().crypto()};
auto postCallState = std::vector<smtutil::Expression>{state().state()} + currentStateVariables(_contract);
std::vector<smtutil::Expression> stateExprs{error, address, state().abi(), state().crypto()};
auto nondet = (*m_nondetInterfaces.at(&_contract))(stateExprs + preCallState + postCallState);
auto nondetCall = callPredicate(stateExprs + preCallState + postCallState);
@ -945,7 +944,7 @@ void CHC::externalFunctionCall(FunctionCall const& _funCall)
if (Expression const* value = valueOption(callOptions))
decreaseBalanceFromOptionsValue(*value);
auto preCallState = vector<smtutil::Expression>{state().state()} + currentStateVariables();
auto preCallState = std::vector<smtutil::Expression>{state().state()} + currentStateVariables();
if (!usesStaticCall(_funCall))
{
@ -962,8 +961,8 @@ void CHC::externalFunctionCall(FunctionCall const& _funCall)
PredicateType::ExternalCallUntrusted,
&_funCall
);
auto postCallState = vector<smtutil::Expression>{state().state()} + currentStateVariables();
vector<smtutil::Expression> stateExprs{error, state().thisAddress(), state().abi(), state().crypto()};
auto postCallState = std::vector<smtutil::Expression>{state().state()} + currentStateVariables();
std::vector<smtutil::Expression> stateExprs{error, state().thisAddress(), state().abi(), state().crypto()};
auto nondet = (*m_nondetInterfaces.at(m_currentContract))(stateExprs + preCallState + postCallState);
auto nondetCall = callPredicate(stateExprs + preCallState + postCallState);
@ -1076,7 +1075,7 @@ void CHC::makeArrayPopVerificationTarget(FunctionCall const& _arrayPop)
auto memberAccess = dynamic_cast<MemberAccess const*>(cleanExpression(_arrayPop.expression()));
solAssert(memberAccess, "");
auto symbArray = dynamic_pointer_cast<SymbolicArrayVariable>(m_context.expression(memberAccess->expression()));
auto symbArray = std::dynamic_pointer_cast<SymbolicArrayVariable>(m_context.expression(memberAccess->expression()));
solAssert(symbArray, "");
verificationTargetEncountered(&_arrayPop, VerificationTargetType::PopEmptyArray, symbArray->length() <= 0);
@ -1089,7 +1088,7 @@ void CHC::makeOutOfBoundsVerificationTarget(IndexAccess const& _indexAccess)
auto baseType = _indexAccess.baseExpression().annotation().type;
optional<smtutil::Expression> length;
std::optional<smtutil::Expression> length;
if (smt::isArray(*baseType))
length = dynamic_cast<smt::SymbolicArrayVariable const&>(
*m_context.expression(_indexAccess.baseExpression())
@ -1097,7 +1096,7 @@ void CHC::makeOutOfBoundsVerificationTarget(IndexAccess const& _indexAccess)
else if (auto const* type = dynamic_cast<FixedBytesType const*>(baseType))
length = smtutil::Expression(static_cast<size_t>(type->numBytes()));
optional<smtutil::Expression> target;
std::optional<smtutil::Expression> target;
if (
auto index = _indexAccess.indexExpression();
index && length
@ -1108,7 +1107,7 @@ void CHC::makeOutOfBoundsVerificationTarget(IndexAccess const& _indexAccess)
verificationTargetEncountered(&_indexAccess, VerificationTargetType::OutOfBounds, *target);
}
pair<smtutil::Expression, smtutil::Expression> CHC::arithmeticOperation(
std::pair<smtutil::Expression, smtutil::Expression> CHC::arithmeticOperation(
Token _op,
smtutil::Expression const& _left,
smtutil::Expression const& _right,
@ -1192,7 +1191,7 @@ void CHC::resetSourceAnalysis()
solAssert(m_settings.solvers.smtlib2 || m_settings.solvers.eld);
if (!m_interface)
m_interface = make_unique<CHCSmtLib2Interface>(m_smtlib2Responses, m_smtCallback, m_settings.solvers, m_settings.timeout);
m_interface = std::make_unique<CHCSmtLib2Interface>(m_smtlib2Responses, m_smtCallback, m_settings.solvers, m_settings.timeout);
auto smtlib2Interface = dynamic_cast<CHCSmtLib2Interface*>(m_interface.get());
solAssert(smtlib2Interface, "");
@ -1249,9 +1248,9 @@ void CHC::setCurrentBlock(Predicate const& _block)
m_currentBlock = predicate(_block);
}
set<unsigned> CHC::transactionVerificationTargetsIds(ASTNode const* _txRoot)
std::set<unsigned> CHC::transactionVerificationTargetsIds(ASTNode const* _txRoot)
{
set<unsigned> verificationTargetsIds;
std::set<unsigned> verificationTargetsIds;
struct ASTNodeCompare: EncodingContext::IdCompare
{
bool operator<(ASTNodeCompare _other) const { return operator()(node, _other.node); }
@ -1273,9 +1272,9 @@ bool CHC::usesStaticCall(FunctionCall const& _funCall)
return (function && (function->stateMutability() == StateMutability::Pure || function->stateMutability() == StateMutability::View)) || kind == FunctionType::Kind::BareStaticCall;
}
optional<CHC::CHCNatspecOption> CHC::natspecOptionFromString(string const& _option)
std::optional<CHC::CHCNatspecOption> CHC::natspecOptionFromString(std::string const& _option)
{
static map<string, CHCNatspecOption> options{
static std::map<std::string, CHCNatspecOption> options{
{"abstract-function-nondet", CHCNatspecOption::AbstractFunctionNondet}
};
if (options.count(_option))
@ -1283,15 +1282,15 @@ optional<CHC::CHCNatspecOption> CHC::natspecOptionFromString(string const& _opti
return {};
}
set<CHC::CHCNatspecOption> CHC::smtNatspecTags(FunctionDefinition const& _function)
std::set<CHC::CHCNatspecOption> CHC::smtNatspecTags(FunctionDefinition const& _function)
{
set<CHC::CHCNatspecOption> options;
string smtStr = "custom:smtchecker";
std::set<CHC::CHCNatspecOption> options;
std::string smtStr = "custom:smtchecker";
bool errorSeen = false;
for (auto const& [tag, value]: _function.annotation().docTags)
if (tag == smtStr)
{
string const& content = value.content;
std::string const& content = value.content;
if (auto option = natspecOptionFromString(content))
options.insert(*option);
else if (!errorSeen)
@ -1327,7 +1326,7 @@ SortPointer CHC::sort(ASTNode const* _node)
return functionBodySort(*m_currentFunction, m_currentContract, state());
}
Predicate const* CHC::createSymbolicBlock(SortPointer _sort, string const& _name, PredicateType _predType, ASTNode const* _node, ContractDefinition const* _contractContext)
Predicate const* CHC::createSymbolicBlock(SortPointer _sort, std::string const& _name, PredicateType _predType, ASTNode const* _node, ContractDefinition const* _contractContext)
{
auto const* block = Predicate::create(_sort, _name, _predType, m_context, _node, _contractContext, m_scopes);
m_interface->registerRelation(block->functor());
@ -1339,7 +1338,7 @@ void CHC::defineInterfacesAndSummaries(SourceUnit const& _source)
for (auto const& node: _source.nodes())
if (auto const* contract = dynamic_cast<ContractDefinition const*>(node.get()))
{
string suffix = contract->name() + "_" + to_string(contract->id());
std::string suffix = contract->name() + "_" + std::to_string(contract->id());
m_interfaces[contract] = createSymbolicBlock(interfaceSort(*contract, state()), "interface_" + uniquePrefix() + "_" + suffix, PredicateType::Interface, contract, contract);
m_nondetInterfaces[contract] = createSymbolicBlock(nondetInterfaceSort(*contract, state()), "nondet_interface_" + uniquePrefix() + "_" + suffix, PredicateType::NondetInterface, contract, contract);
m_constructorSummaries[contract] = createConstructorBlock(*contract, "summary_constructor");
@ -1385,10 +1384,10 @@ void CHC::defineInterfacesAndSummaries(SourceUnit const& _source)
auto errorPost = errorFlag().increaseIndex();
auto nondetPost = smt::nondetInterface(iface, *contract, m_context, 0, 2);
vector<smtutil::Expression> args{errorPost, state().thisAddress(), state().abi(), state().crypto(), state().tx(), state().state(1)};
std::vector<smtutil::Expression> args{errorPost, state().thisAddress(), state().abi(), state().crypto(), state().tx(), state().state(1)};
args += state1 +
applyMap(function->parameters(), [this](auto _var) { return valueAtIndex(*_var, 0); }) +
vector<smtutil::Expression>{state().state(2)} +
std::vector<smtutil::Expression>{state().state(2)} +
state2 +
applyMap(function->parameters(), [this](auto _var) { return valueAtIndex(*_var, 1); }) +
applyMap(function->returnParameters(), [this](auto _var) { return valueAtIndex(*_var, 1); });
@ -1416,7 +1415,7 @@ void CHC::defineExternalFunctionInterface(FunctionDefinition const& _function, C
// block.coinbase, which do not trigger calls into the contract.
// So the only constraint we can add here is that the balance of
// the contract grows by at least `msg.value`.
SymbolicIntVariable k{TypeProvider::uint256(), TypeProvider::uint256(), "funds_" + to_string(m_context.newUniqueId()), m_context};
SymbolicIntVariable k{TypeProvider::uint256(), TypeProvider::uint256(), "funds_" + std::to_string(m_context.newUniqueId()), m_context};
m_context.addAssertion(k.currentValue() >= state().txMember("msg.value"));
// Assume that address(this).balance cannot overflow.
m_context.addAssertion(smt::symbolicUnknownConstraints(state().balance(state().thisAddress()) + k.currentValue(), TypeProvider::uint256()));
@ -1582,7 +1581,7 @@ smtutil::Expression CHC::externalSummary(FunctionDefinition const& _function)
return externalSummary(_function, *m_currentContract);
}
Predicate const* CHC::createBlock(ASTNode const* _node, PredicateType _predType, string const& _prefix)
Predicate const* CHC::createBlock(ASTNode const* _node, PredicateType _predType, std::string const& _prefix)
{
auto block = createSymbolicBlock(
sort(_node),
@ -1607,7 +1606,7 @@ Predicate const* CHC::createSummaryBlock(FunctionDefinition const& _function, Co
);
}
Predicate const* CHC::createConstructorBlock(ContractDefinition const& _contract, string const& _prefix)
Predicate const* CHC::createConstructorBlock(ContractDefinition const& _contract, std::string const& _prefix)
{
return createSymbolicBlock(
constructorSort(_contract, state()),
@ -1622,7 +1621,7 @@ void CHC::createErrorBlock()
{
m_errorPredicate = createSymbolicBlock(
arity0FunctionSort(),
"error_target_" + to_string(m_context.newUniqueId()),
"error_target_" + std::to_string(m_context.newUniqueId()),
PredicateType::Error
);
m_interface->registerRelation(m_errorPredicate->functor());
@ -1650,18 +1649,18 @@ smtutil::Expression CHC::initialConstraints(ContractDefinition const& _contract,
return conj;
}
vector<smtutil::Expression> CHC::initialStateVariables()
std::vector<smtutil::Expression> CHC::initialStateVariables()
{
return stateVariablesAtIndex(0);
}
vector<smtutil::Expression> CHC::stateVariablesAtIndex(unsigned _index)
std::vector<smtutil::Expression> CHC::stateVariablesAtIndex(unsigned _index)
{
solAssert(m_currentContract, "");
return stateVariablesAtIndex(_index, *m_currentContract);
}
vector<smtutil::Expression> CHC::stateVariablesAtIndex(unsigned _index, ContractDefinition const& _contract)
std::vector<smtutil::Expression> CHC::stateVariablesAtIndex(unsigned _index, ContractDefinition const& _contract)
{
return applyMap(
SMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract),
@ -1669,27 +1668,27 @@ vector<smtutil::Expression> CHC::stateVariablesAtIndex(unsigned _index, Contract
);
}
vector<smtutil::Expression> CHC::currentStateVariables()
std::vector<smtutil::Expression> CHC::currentStateVariables()
{
solAssert(m_currentContract, "");
return currentStateVariables(*m_currentContract);
}
vector<smtutil::Expression> CHC::currentStateVariables(ContractDefinition const& _contract)
std::vector<smtutil::Expression> CHC::currentStateVariables(ContractDefinition const& _contract)
{
return applyMap(SMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract), [this](auto _var) { return currentValue(*_var); });
}
smtutil::Expression CHC::currentEqualInitialVarsConstraints(vector<VariableDeclaration const*> const& _vars) const
smtutil::Expression CHC::currentEqualInitialVarsConstraints(std::vector<VariableDeclaration const*> const& _vars) const
{
return fold(_vars, smtutil::Expression(true), [this](auto&& _conj, auto _var) {
return std::move(_conj) && currentValue(*_var) == m_context.variable(*_var)->valueAtIndex(0);
});
}
string CHC::predicateName(ASTNode const* _node, ContractDefinition const* _contract)
std::string CHC::predicateName(ASTNode const* _node, ContractDefinition const* _contract)
{
string prefix;
std::string prefix;
if (auto funDef = dynamic_cast<FunctionDefinition const*>(_node))
{
prefix += TokenTraits::toString(funDef->kind());
@ -1701,7 +1700,7 @@ string CHC::predicateName(ASTNode const* _node, ContractDefinition const* _contr
auto contract = _contract ? _contract : m_currentContract;
solAssert(contract, "");
return prefix + "_" + to_string(_node->id()) + "_" + to_string(contract->id());
return prefix + "_" + std::to_string(_node->id()) + "_" + std::to_string(contract->id());
}
smtutil::Expression CHC::predicate(Predicate const& _block)
@ -1756,7 +1755,7 @@ smtutil::Expression CHC::predicate(FunctionCall const& _funCall)
solAssert(false, "Unreachable!");
};
errorFlag().increaseIndex();
vector<smtutil::Expression> args{errorFlag().currentValue(), contractAddressValue(_funCall), state().abi(), state().crypto(), state().tx(), state().state()};
std::vector<smtutil::Expression> args{errorFlag().currentValue(), contractAddressValue(_funCall), state().abi(), state().crypto(), state().tx(), state().state()};
auto const* contract = function->annotation().contract;
auto const& hierarchy = m_currentContract->annotation().linearizedBaseContracts;
@ -1773,7 +1772,7 @@ smtutil::Expression CHC::predicate(FunctionCall const& _funCall)
for (auto const& var: stateVariablesIncludingInheritedAndPrivate(*contract))
m_context.variable(*var)->increaseIndex();
}
args += vector<smtutil::Expression>{state().state()};
args += std::vector<smtutil::Expression>{state().state()};
args += currentStateVariables(*contract);
for (auto var: function->parameters() + function->returnParameters())
@ -1798,12 +1797,12 @@ smtutil::Expression CHC::predicate(FunctionCall const& _funCall)
return callPredicate(args);
}
void CHC::addRule(smtutil::Expression const& _rule, string const& _ruleName)
void CHC::addRule(smtutil::Expression const& _rule, std::string const& _ruleName)
{
m_interface->addRule(_rule, _ruleName);
}
tuple<CheckResult, smtutil::Expression, CHCSolverInterface::CexGraph> CHC::query(smtutil::Expression const& _query, langutil::SourceLocation const& _location)
std::tuple<CheckResult, smtutil::Expression, CHCSolverInterface::CexGraph> CHC::query(smtutil::Expression const& _query, langutil::SourceLocation const& _location)
{
CheckResult result;
smtutil::Expression invariant(true);
@ -1812,13 +1811,13 @@ tuple<CheckResult, smtutil::Expression, CHCSolverInterface::CexGraph> CHC::query
{
auto smtLibInterface = dynamic_cast<CHCSmtLib2Interface*>(m_interface.get());
solAssert(smtLibInterface, "Requested to print queries but CHCSmtLib2Interface not available");
string smtLibCode = smtLibInterface->dumpQuery(_query);
std::string smtLibCode = smtLibInterface->dumpQuery(_query);
m_errorReporter.info(
2339_error,
"CHC: Requested query:\n" + smtLibCode
);
}
tie(result, invariant, cex) = m_interface->query(_query);
std::tie(result, invariant, cex) = m_interface->query(_query);
switch (result)
{
case CheckResult::SATISFIABLE:
@ -1836,7 +1835,7 @@ tuple<CheckResult, smtutil::Expression, CHCSolverInterface::CexGraph> CHC::query
CheckResult resultNoOpt;
smtutil::Expression invariantNoOpt(true);
CHCSolverInterface::CexGraph cexNoOpt;
tie(resultNoOpt, invariantNoOpt, cexNoOpt) = m_interface->query(_query);
std::tie(resultNoOpt, invariantNoOpt, cexNoOpt) = m_interface->query(_query);
if (resultNoOpt == CheckResult::SATISFIABLE)
cex = std::move(cexNoOpt);
@ -1902,7 +1901,7 @@ void CHC::verificationTargetEncountered(
m_context.addAssertion(errorFlag().currentValue() == previousError);
}
pair<string, ErrorId> CHC::targetDescription(CHCVerificationTarget const& _target)
std::pair<std::string, ErrorId> CHC::targetDescription(CHCVerificationTarget const& _target)
{
if (_target.type == VerificationTargetType::PopEmptyArray)
{
@ -1950,7 +1949,7 @@ void CHC::checkVerificationTargets()
// Also, all possible contexts in which an external function can be called has been recorded (m_queryPlaceholders).
// Here we combine every context in which an external function can be called with all possible verification conditions
// in its call graph. Each such combination forms a unique verification target.
map<unsigned, vector<CHCQueryPlaceholder>> targetEntryPoints;
std::map<unsigned, std::vector<CHCQueryPlaceholder>> targetEntryPoints;
for (auto const& [function, placeholders]: m_queryPlaceholders)
{
auto functionTargets = transactionVerificationTargetsIds(function);
@ -1959,7 +1958,7 @@ void CHC::checkVerificationTargets()
targetEntryPoints[id].push_back(placeholder);
}
set<unsigned> checkedErrorIds;
std::set<unsigned> checkedErrorIds;
for (auto const& [targetId, placeholders]: targetEntryPoints)
{
auto const& target = m_verificationTargets.at(targetId);
@ -1988,7 +1987,7 @@ void CHC::checkVerificationTargets()
5840_error,
{},
"CHC: " +
to_string(m_unprovedTargets.size()) +
std::to_string(m_unprovedTargets.size()) +
" verification condition(s) could not be proved." +
" Enable the model checker option \"show unproved\" to see all of them." +
" Consider choosing a specific contract to be verified in order to reduce the solving problems." +
@ -1999,7 +1998,7 @@ void CHC::checkVerificationTargets()
m_errorReporter.info(
1391_error,
"CHC: " +
to_string(m_safeTargets.size()) +
std::to_string(m_safeTargets.size()) +
" verification condition(s) proved safe!" +
" Enable the model checker option \"show proved safe\" to see all of them."
);
@ -2016,17 +2015,17 @@ void CHC::checkVerificationTargets()
if (!m_settings.invariants.invariants.empty())
{
string msg;
std::string msg;
for (auto pred: m_invariants | ranges::views::keys)
{
ASTNode const* node = pred->programNode();
string what;
std::string what;
if (auto contract = dynamic_cast<ContractDefinition const*>(node))
what = contract->fullyQualifiedName();
else
solAssert(false, "");
string invType;
std::string invType;
if (pred->type() == PredicateType::Interface)
invType = "Contract invariant(s)";
else if (pred->type() == PredicateType::NondetInterface)
@ -2038,16 +2037,16 @@ void CHC::checkVerificationTargets()
for (auto const& inv: m_invariants.at(pred))
msg += inv + "\n";
}
if (msg.find("<errorCode>") != string::npos)
if (msg.find("<errorCode>") != std::string::npos)
{
set<unsigned> seenErrors;
std::set<unsigned> seenErrors;
msg += "<errorCode> = 0 -> no errors\n";
for (auto const& [id, target]: m_verificationTargets)
if (!seenErrors.count(target.errorId))
{
seenErrors.insert(target.errorId);
string loc = string(m_charStreamProvider.charStream(*target.errorNode->location().sourceName).text(target.errorNode->location()));
msg += "<errorCode> = " + to_string(target.errorId) + " -> " + ModelCheckerTargets::targetTypeToString.at(target.type) + " at " + loc + "\n";
std::string loc = std::string(m_charStreamProvider.charStream(*target.errorNode->location().sourceName).text(target.errorNode->location()));
msg += "<errorCode> = " + std::to_string(target.errorId) + " -> " + ModelCheckerTargets::targetTypeToString.at(target.type) + " at " + loc + "\n";
}
}
@ -2058,12 +2057,12 @@ void CHC::checkVerificationTargets()
// There can be targets in internal functions that are not reachable from the external interface.
// These are safe by definition and are not even checked by the CHC engine, but this information
// must still be reported safe by the BMC engine.
set<unsigned> allErrorIds;
std::set<unsigned> allErrorIds;
for (auto const& entry: m_functionTargetIds)
for (unsigned id: entry.second)
allErrorIds.insert(id);
set<unsigned> unreachableErrorIds;
std::set<unsigned> unreachableErrorIds;
set_difference(
allErrorIds.begin(),
allErrorIds.end(),
@ -2077,10 +2076,10 @@ void CHC::checkVerificationTargets()
void CHC::checkAndReportTarget(
CHCVerificationTarget const& _target,
vector<CHCQueryPlaceholder> const& _placeholders,
std::vector<CHCQueryPlaceholder> const& _placeholders,
ErrorId _errorReporterId,
string _satMsg,
string _unknownMsg
std::string _satMsg,
std::string _unknownMsg
)
{
if (m_unsafeTargets.count(_target.errorNode) && m_unsafeTargets.at(_target.errorNode).count(_target.type))
@ -2098,12 +2097,12 @@ void CHC::checkAndReportTarget(
if (result == CheckResult::UNSATISFIABLE)
{
m_safeTargets[_target.errorNode].insert(_target);
set<Predicate const*> predicates;
std::set<Predicate const*> predicates;
for (auto const* pred: m_interfaces | ranges::views::values)
predicates.insert(pred);
for (auto const* pred: m_nondetInterfaces | ranges::views::values)
predicates.insert(pred);
map<Predicate const*, set<string>> invariants = collectInvariants(invariant, predicates, m_settings.invariants);
std::map<Predicate const*, std::set<std::string>> invariants = collectInvariants(invariant, predicates, m_settings.invariants);
for (auto pred: invariants | ranges::views::keys)
m_invariants[pred] += std::move(invariants.at(pred));
}
@ -2153,9 +2152,9 @@ the function summaries in the callgraph of the error node is the reverse transac
The first function summary seen contains the values for the state, input and output variables at the
error point.
*/
optional<string> CHC::generateCounterexample(CHCSolverInterface::CexGraph const& _graph, string const& _root)
std::optional<std::string> CHC::generateCounterexample(CHCSolverInterface::CexGraph const& _graph, std::string const& _root)
{
optional<unsigned> rootId;
std::optional<unsigned> rootId;
for (auto const& [id, node]: _graph.nodes)
if (node.name == _root)
{
@ -2165,8 +2164,8 @@ optional<string> CHC::generateCounterexample(CHCSolverInterface::CexGraph const&
if (!rootId)
return {};
vector<string> path;
string localState;
std::vector<std::string> path;
std::string localState;
auto callGraph = summaryCalls(_graph, *rootId);
@ -2204,7 +2203,7 @@ optional<string> CHC::generateCounterexample(CHCSolverInterface::CexGraph const&
if (auto outStr = formatVariableModel(outParams, outValues, "\n"); !outStr.empty())
localState += outStr + "\n";
optional<unsigned> localErrorId;
std::optional<unsigned> localErrorId;
solidity::util::BreadthFirstSearch<unsigned> bfs{{summaryId}};
bfs.run([&](auto _nodeId, auto&& _addChild) {
auto const& children = _graph.edges.at(_nodeId);
@ -2239,9 +2238,9 @@ optional<string> CHC::generateCounterexample(CHCSolverInterface::CexGraph const&
}
}
string txCex = summaryPredicate->formatSummaryCall(summaryArgs, m_charStreamProvider);
std::string txCex = summaryPredicate->formatSummaryCall(summaryArgs, m_charStreamProvider);
list<string> calls;
std::list<std::string> calls;
auto dfs = [&](unsigned parent, unsigned node, unsigned depth, auto&& _dfs) -> void {
auto pred = nodePred(node);
auto parentPred = nodePred(parent);
@ -2254,7 +2253,7 @@ optional<string> CHC::generateCounterexample(CHCSolverInterface::CexGraph const&
bool appendTxVars = pred->isConstructorSummary() || pred->isFunctionSummary() || pred->isExternalCallUntrusted();
calls.push_front(string(depth * 4, ' ') + pred->formatSummaryCall(nodeArgs(node), m_charStreamProvider, appendTxVars));
calls.push_front(std::string(depth * 4, ' ') + pred->formatSummaryCall(nodeArgs(node), m_charStreamProvider, appendTxVars));
if (pred->isInternalCall())
calls.front() += " -- internal call";
else if (pred->isExternalCallTrusted())
@ -2281,12 +2280,12 @@ optional<string> CHC::generateCounterexample(CHCSolverInterface::CexGraph const&
return localState + "\nTransaction trace:\n" + boost::algorithm::join(path | ranges::views::reverse, "\n");
}
map<unsigned, vector<unsigned>> CHC::summaryCalls(CHCSolverInterface::CexGraph const& _graph, unsigned _root)
std::map<unsigned, std::vector<unsigned>> CHC::summaryCalls(CHCSolverInterface::CexGraph const& _graph, unsigned _root)
{
map<unsigned, vector<unsigned>> calls;
std::map<unsigned, std::vector<unsigned>> calls;
auto compare = [&](unsigned _a, unsigned _b) {
auto extract = [&](string const& _s) {
auto extract = [&](std::string const& _s) {
// We want to sort sibling predicates in the counterexample graph by their unique predicate id.
// For most predicates, this actually doesn't matter.
// The cases where this matters are internal and external function calls which have the form:
@ -2312,7 +2311,7 @@ map<unsigned, vector<unsigned>> CHC::summaryCalls(CHCSolverInterface::CexGraph c
return extract(_graph.nodes.at(_a).name) > extract(_graph.nodes.at(_b).name);
};
queue<pair<unsigned, unsigned>> q;
std::queue<std::pair<unsigned, unsigned>> q;
q.push({_root, _root});
while (!q.empty())
{
@ -2334,19 +2333,19 @@ map<unsigned, vector<unsigned>> CHC::summaryCalls(CHCSolverInterface::CexGraph c
root = node;
}
auto const& edges = _graph.edges.at(node);
for (unsigned v: set<unsigned, decltype(compare)>(begin(edges), end(edges), compare))
for (unsigned v: std::set<unsigned, decltype(compare)>(begin(edges), end(edges), compare))
q.push({v, root});
}
return calls;
}
string CHC::cex2dot(CHCSolverInterface::CexGraph const& _cex)
std::string CHC::cex2dot(CHCSolverInterface::CexGraph const& _cex)
{
string dot = "digraph {\n";
std::string dot = "digraph {\n";
auto pred = [&](CHCSolverInterface::CexNode const& _node) {
vector<string> args = applyMap(
std::vector<std::string> args = applyMap(
_node.arguments,
[&](auto const& arg) { return arg.name; }
);
@ -2361,14 +2360,14 @@ string CHC::cex2dot(CHCSolverInterface::CexGraph const& _cex)
return dot;
}
string CHC::uniquePrefix()
std::string CHC::uniquePrefix()
{
return to_string(m_blockCounter++);
return std::to_string(m_blockCounter++);
}
string CHC::contractSuffix(ContractDefinition const& _contract)
std::string CHC::contractSuffix(ContractDefinition const& _contract)
{
return _contract.name() + "_" + to_string(_contract.id());
return _contract.name() + "_" + std::to_string(_contract.id());
}
unsigned CHC::newErrorId()

View File

@ -20,7 +20,6 @@
#include <libsolidity/formal/SymbolicTypes.h>
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::frontend::smt;
@ -51,7 +50,7 @@ unsigned EncodingContext::newUniqueId()
/// Variables.
shared_ptr<SymbolicVariable> EncodingContext::variable(frontend::VariableDeclaration const& _varDecl)
std::shared_ptr<SymbolicVariable> EncodingContext::variable(frontend::VariableDeclaration const& _varDecl)
{
solAssert(knownVariable(_varDecl), "");
return m_variables[&_varDecl];
@ -61,7 +60,7 @@ bool EncodingContext::createVariable(frontend::VariableDeclaration const& _varDe
{
solAssert(!knownVariable(_varDecl), "");
auto const& type = _varDecl.type();
auto result = newSymbolicVariable(*type, _varDecl.name() + "_" + to_string(_varDecl.id()), *this);
auto result = newSymbolicVariable(*type, _varDecl.name() + "_" + std::to_string(_varDecl.id()), *this);
m_variables.emplace(&_varDecl, result.second);
return result.first;
}
@ -77,13 +76,13 @@ void EncodingContext::resetVariable(frontend::VariableDeclaration const& _variab
setUnknownValue(_variable);
}
void EncodingContext::resetVariables(set<frontend::VariableDeclaration const*> const& _variables)
void EncodingContext::resetVariables(std::set<frontend::VariableDeclaration const*> const& _variables)
{
for (auto const* decl: _variables)
resetVariable(*decl);
}
void EncodingContext::resetVariables(function<bool(frontend::VariableDeclaration const&)> const& _filter)
void EncodingContext::resetVariables(std::function<bool(frontend::VariableDeclaration const&)> const& _filter)
{
for_each(begin(m_variables), end(m_variables), [&](auto _variable)
{
@ -127,14 +126,14 @@ void EncodingContext::setUnknownValue(SymbolicVariable& _variable)
/// Expressions
shared_ptr<SymbolicVariable> EncodingContext::expression(frontend::Expression const& _e)
std::shared_ptr<SymbolicVariable> EncodingContext::expression(frontend::Expression const& _e)
{
if (!knownExpression(_e))
createExpression(_e);
return m_expressions.at(&_e);
}
bool EncodingContext::createExpression(frontend::Expression const& _e, shared_ptr<SymbolicVariable> _symbVar)
bool EncodingContext::createExpression(frontend::Expression const& _e, std::shared_ptr<SymbolicVariable> _symbVar)
{
solAssert(_e.annotation().type, "");
if (knownExpression(_e))
@ -149,7 +148,7 @@ bool EncodingContext::createExpression(frontend::Expression const& _e, shared_pt
}
else
{
auto result = newSymbolicVariable(*_e.annotation().type, "expr_" + to_string(_e.id()), *this);
auto result = newSymbolicVariable(*_e.annotation().type, "expr_" + std::to_string(_e.id()), *this);
m_expressions.emplace(&_e, result.second);
return result.first;
}
@ -162,13 +161,13 @@ bool EncodingContext::knownExpression(frontend::Expression const& _e) const
/// Global variables and functions.
shared_ptr<SymbolicVariable> EncodingContext::globalSymbol(string const& _name)
std::shared_ptr<SymbolicVariable> EncodingContext::globalSymbol(std::string const& _name)
{
solAssert(knownGlobalSymbol(_name), "");
return m_globalContext.at(_name);
}
bool EncodingContext::createGlobalSymbol(string const& _name, frontend::Expression const& _expr)
bool EncodingContext::createGlobalSymbol(std::string const& _name, frontend::Expression const& _expr)
{
solAssert(!knownGlobalSymbol(_name), "");
auto result = newSymbolicVariable(*_expr.annotation().type, _name, *this);
@ -177,7 +176,7 @@ bool EncodingContext::createGlobalSymbol(string const& _name, frontend::Expressi
return result.first;
}
bool EncodingContext::knownGlobalSymbol(string const& _var) const
bool EncodingContext::knownGlobalSymbol(std::string const& _var) const
{
return m_globalContext.count(_var);
}

View File

@ -29,7 +29,6 @@
#include <vector>
#include <string>
using namespace std;
using boost::algorithm::starts_with;
using namespace solidity;
using namespace solidity::util;
@ -42,7 +41,7 @@ namespace solidity::frontend::smt
namespace
{
string formatDatatypeAccessor(smtutil::Expression const& _expr, vector<string> const& _args)
std::string formatDatatypeAccessor(smtutil::Expression const& _expr, std::vector<std::string> const& _args)
{
auto const& op = _expr.name;
@ -63,9 +62,9 @@ string formatDatatypeAccessor(smtutil::Expression const& _expr, vector<string> c
if (op == "dt_accessor_ecrecover")
return "ecrecover";
string accessorStr = "accessor_";
std::string accessorStr = "accessor_";
// Struct members have suffix "accessor_<memberName>".
string type = op.substr(op.rfind(accessorStr) + accessorStr.size());
std::string type = op.substr(op.rfind(accessorStr) + accessorStr.size());
solAssert(_expr.arguments.size() == 1, "");
if (type == "length")
@ -87,22 +86,22 @@ string formatDatatypeAccessor(smtutil::Expression const& _expr, vector<string> c
return _args.at(0) + "." + type;
}
string formatGenericOp(smtutil::Expression const& _expr, vector<string> const& _args)
std::string formatGenericOp(smtutil::Expression const& _expr, std::vector<std::string> const& _args)
{
return _expr.name + "(" + boost::algorithm::join(_args, ", ") + ")";
}
string formatInfixOp(string const& _op, vector<string> const& _args)
std::string formatInfixOp(std::string const& _op, std::vector<std::string> const& _args)
{
return "(" + boost::algorithm::join(_args, " " + _op + " ") + ")";
}
string formatArrayOp(smtutil::Expression const& _expr, vector<string> const& _args)
std::string formatArrayOp(smtutil::Expression const& _expr, std::vector<std::string> const& _args)
{
if (_expr.name == "select")
{
auto const& a0 = _args.at(0);
static set<string> const ufs{"keccak256", "sha256", "ripemd160", "ecrecover"};
static std::set<std::string> const ufs{"keccak256", "sha256", "ripemd160", "ecrecover"};
if (ufs.count(a0) || starts_with(a0, "t_function_abi"))
return _args.at(0) + "(" + _args.at(1) + ")";
return _args.at(0) + "[" + _args.at(1) + "]";
@ -112,7 +111,7 @@ string formatArrayOp(smtutil::Expression const& _expr, vector<string> const& _ar
return formatGenericOp(_expr, _args);
}
string formatUnaryOp(smtutil::Expression const& _expr, vector<string> const& _args)
std::string formatUnaryOp(smtutil::Expression const& _expr, std::vector<std::string> const& _args)
{
if (_expr.name == "not")
return "!" + _args.at(0);
@ -122,7 +121,7 @@ string formatUnaryOp(smtutil::Expression const& _expr, vector<string> const& _ar
}
smtutil::Expression substitute(smtutil::Expression _from, map<string, string> const& _subst)
smtutil::Expression substitute(smtutil::Expression _from, std::map<std::string, std::string> const& _subst)
{
// TODO For now we ignore nested quantifier expressions,
// but we should support them in the future.
@ -135,7 +134,7 @@ smtutil::Expression substitute(smtutil::Expression _from, map<string, string> co
return _from;
}
string toSolidityStr(smtutil::Expression const& _expr)
std::string toSolidityStr(smtutil::Expression const& _expr)
{
auto const& op = _expr.name;
@ -150,7 +149,7 @@ string toSolidityStr(smtutil::Expression const& _expr)
return formatDatatypeAccessor(_expr, strArgs);
// Infix operators with format replacements.
static map<string, string> const infixOps{
static std::map<std::string, std::string> const infixOps{
{"and", "&&"},
{"or", "||"},
{"implies", "=>"},
@ -170,7 +169,7 @@ string toSolidityStr(smtutil::Expression const& _expr)
if (infixOps.count(op))
return formatInfixOp(infixOps.at(op), strArgs);
static set<string> const arrayOps{"select", "store", "const_array"};
static std::set<std::string> const arrayOps{"select", "store", "const_array"};
if (arrayOps.count(op))
return formatArrayOp(_expr, strArgs);

View File

@ -25,7 +25,6 @@
#include <boost/algorithm/string.hpp>
using namespace std;
using boost::algorithm::starts_with;
using namespace solidity;
using namespace solidity::smtutil;
@ -34,19 +33,19 @@ using namespace solidity::frontend::smt;
namespace solidity::frontend::smt
{
map<Predicate const*, set<string>> collectInvariants(
std::map<Predicate const*, std::set<std::string>> collectInvariants(
smtutil::Expression const& _proof,
set<Predicate const*> const& _predicates,
std::set<Predicate const*> const& _predicates,
ModelCheckerInvariants const& _invariantsSetting
)
{
set<string> targets;
std::set<std::string> targets;
if (_invariantsSetting.has(InvariantType::Contract))
targets.insert("interface_");
if (_invariantsSetting.has(InvariantType::Reentrancy))
targets.insert("nondet_interface_");
map<string, pair<smtutil::Expression, smtutil::Expression>> equalities;
std::map<std::string, std::pair<smtutil::Expression, smtutil::Expression>> equalities;
// Collect equalities where one of the sides is a predicate we're interested in.
util::BreadthFirstSearch<smtutil::Expression const*>{{&_proof}}.run([&](auto&& _expr, auto&& _addChild) {
if (_expr->name == "=")
@ -63,7 +62,7 @@ map<Predicate const*, set<string>> collectInvariants(
_addChild(&arg);
});
map<Predicate const*, set<string>> invariants;
std::map<Predicate const*, std::set<std::string>> invariants;
for (auto pred: _predicates)
{
auto predName = pred->functor().name;
@ -74,7 +73,7 @@ map<Predicate const*, set<string>> collectInvariants(
auto const& [predExpr, invExpr] = equalities.at(predName);
static set<string> const ignore{"true", "false"};
static std::set<std::string> const ignore{"true", "false"};
auto r = substitute(invExpr, pred->expressionSubstitution(predExpr));
// No point in reporting true/false as invariants.
if (!ignore.count(r.name))

View File

@ -31,7 +31,6 @@
#include <range/v3/algorithm/any_of.hpp>
#include <range/v3/view.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::langutil;
@ -41,7 +40,7 @@ using namespace solidity::smtutil;
ModelChecker::ModelChecker(
ErrorReporter& _errorReporter,
langutil::CharStreamProvider const& _charStreamProvider,
map<h256, string> const& _smtlib2Responses,
std::map<h256, std::string> const& _smtlib2Responses,
ModelCheckerSettings _settings,
ReadCallback::Callback const& _smtCallback
):
@ -54,19 +53,19 @@ ModelChecker::ModelChecker(
}
// TODO This should be removed for 0.9.0.
bool ModelChecker::isPragmaPresent(vector<shared_ptr<SourceUnit>> const& _sources)
bool ModelChecker::isPragmaPresent(std::vector<std::shared_ptr<SourceUnit>> const& _sources)
{
return ranges::any_of(_sources, [](auto _source) {
return _source && _source->annotation().experimentalFeatures.count(ExperimentalFeature::SMTChecker);
});
}
void ModelChecker::checkRequestedSourcesAndContracts(vector<shared_ptr<SourceUnit>> const& _sources)
void ModelChecker::checkRequestedSourcesAndContracts(std::vector<std::shared_ptr<SourceUnit>> const& _sources)
{
map<string, set<string>> exist;
std::map<std::string, std::set<std::string>> exist;
for (auto const& source: _sources)
for (auto node: source->nodes())
if (auto contract = dynamic_pointer_cast<ContractDefinition>(node))
if (auto contract = std::dynamic_pointer_cast<ContractDefinition>(node))
exist[contract->sourceUnitName()].insert(contract->name());
// Requested sources
@ -100,7 +99,7 @@ void ModelChecker::analyze(SourceUnit const& _source)
{
PragmaDirective const* smtPragma = nullptr;
for (auto node: _source.nodes())
if (auto pragma = dynamic_pointer_cast<PragmaDirective>(node))
if (auto pragma = std::dynamic_pointer_cast<PragmaDirective>(node))
if (
pragma->literals().size() >= 2 &&
pragma->literals().at(1) == "SMTChecker"
@ -125,7 +124,7 @@ void ModelChecker::analyze(SourceUnit const& _source)
if (m_settings.engine.chc)
m_chc.analyze(_source);
map<ASTNode const*, set<VerificationTargetType>, smt::EncodingContext::IdCompare> solvedTargets;
std::map<ASTNode const*, std::set<VerificationTargetType>, smt::EncodingContext::IdCompare> solvedTargets;
for (auto const& [node, targets]: m_chc.safeTargets())
for (auto const& target: targets)
@ -147,7 +146,7 @@ void ModelChecker::analyze(SourceUnit const& _source)
5724_error,
{},
"SMTChecker: " +
to_string(m_unsupportedErrorReporter.errors().size()) +
std::to_string(m_unsupportedErrorReporter.errors().size()) +
" unsupported language feature(s)."
" Enable the model checker option \"show unsupported\" to see all of them."
);
@ -156,7 +155,7 @@ void ModelChecker::analyze(SourceUnit const& _source)
m_uniqueErrorReporter.clear();
}
vector<string> ModelChecker::unhandledQueries()
std::vector<std::string> ModelChecker::unhandledQueries()
{
return m_bmc.unhandledQueries() + m_chc.unhandledQueries();
}
@ -212,7 +211,7 @@ SMTSolverChoice ModelChecker::checkRequestedSolvers(SMTSolverChoice _enabled, Er
SourceLocation(),
"Solver z3 was selected for SMTChecker but it is not available."
#ifdef HAVE_Z3_DLOPEN
" libz3.so." + to_string(Z3_MAJOR_VERSION) + "." + to_string(Z3_MINOR_VERSION) + " was not found."
" libz3.so." + std::to_string(Z3_MAJOR_VERSION) + "." + std::to_string(Z3_MINOR_VERSION) + " was not found."
#endif
);
}

View File

@ -21,18 +21,17 @@
#include <optional>
#include <range/v3/view.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
map<string, InvariantType> const ModelCheckerInvariants::validInvariants{
std::map<std::string, InvariantType> const ModelCheckerInvariants::validInvariants{
{"contract", InvariantType::Contract},
{"reentrancy", InvariantType::Reentrancy}
};
std::optional<ModelCheckerInvariants> ModelCheckerInvariants::fromString(string const& _invs)
std::optional<ModelCheckerInvariants> ModelCheckerInvariants::fromString(std::string const& _invs)
{
set<InvariantType> chosenInvs;
std::set<InvariantType> chosenInvs;
if (_invs == "default")
{
// The default is that no invariants are reported.
@ -41,7 +40,7 @@ std::optional<ModelCheckerInvariants> ModelCheckerInvariants::fromString(string
for (auto&& v: validInvariants | ranges::views::values)
chosenInvs.insert(v);
else
for (auto&& t: _invs | ranges::views::split(',') | ranges::to<vector<string>>())
for (auto&& t: _invs | ranges::views::split(',') | ranges::to<std::vector<std::string>>())
{
if (!validInvariants.count(t))
return {};
@ -51,7 +50,7 @@ std::optional<ModelCheckerInvariants> ModelCheckerInvariants::fromString(string
return ModelCheckerInvariants{chosenInvs};
}
bool ModelCheckerInvariants::setFromString(string const& _inv)
bool ModelCheckerInvariants::setFromString(std::string const& _inv)
{
if (!validInvariants.count(_inv))
return false;
@ -60,7 +59,7 @@ bool ModelCheckerInvariants::setFromString(string const& _inv)
}
using TargetType = VerificationTargetType;
map<string, TargetType> const ModelCheckerTargets::targetStrings{
std::map<std::string, TargetType> const ModelCheckerTargets::targetStrings{
{"constantCondition", TargetType::ConstantCondition},
{"underflow", TargetType::Underflow},
{"overflow", TargetType::Overflow},
@ -71,7 +70,7 @@ map<string, TargetType> const ModelCheckerTargets::targetStrings{
{"outOfBounds", TargetType::OutOfBounds}
};
map<TargetType, string> const ModelCheckerTargets::targetTypeToString{
std::map<TargetType, std::string> const ModelCheckerTargets::targetTypeToString{
{TargetType::ConstantCondition, "Constant condition"},
{TargetType::Underflow, "Underflow"},
{TargetType::Overflow, "Overflow"},
@ -82,9 +81,9 @@ map<TargetType, string> const ModelCheckerTargets::targetTypeToString{
{TargetType::OutOfBounds, "Out of bounds access"}
};
std::optional<ModelCheckerTargets> ModelCheckerTargets::fromString(string const& _targets)
std::optional<ModelCheckerTargets> ModelCheckerTargets::fromString(std::string const& _targets)
{
set<TargetType> chosenTargets;
std::set<TargetType> chosenTargets;
if (_targets == "default" || _targets == "all")
{
bool all = _targets == "all";
@ -96,7 +95,7 @@ std::optional<ModelCheckerTargets> ModelCheckerTargets::fromString(string const&
}
}
else
for (auto&& t: _targets | ranges::views::split(',') | ranges::to<vector<string>>())
for (auto&& t: _targets | ranges::views::split(',') | ranges::to<std::vector<std::string>>())
{
if (!targetStrings.count(t))
return {};
@ -106,7 +105,7 @@ std::optional<ModelCheckerTargets> ModelCheckerTargets::fromString(string const&
return ModelCheckerTargets{chosenTargets};
}
bool ModelCheckerTargets::setFromString(string const& _target)
bool ModelCheckerTargets::setFromString(std::string const& _target)
{
if (!targetStrings.count(_target))
return false;
@ -114,15 +113,15 @@ bool ModelCheckerTargets::setFromString(string const& _target)
return true;
}
std::optional<ModelCheckerContracts> ModelCheckerContracts::fromString(string const& _contracts)
std::optional<ModelCheckerContracts> ModelCheckerContracts::fromString(std::string const& _contracts)
{
map<string, set<string>> chosen;
std::map<std::string, std::set<std::string>> chosen;
if (_contracts == "default")
return ModelCheckerContracts::Default();
for (auto&& sourceContract: _contracts | ranges::views::split(',') | ranges::to<vector<string>>())
for (auto&& sourceContract: _contracts | ranges::views::split(',') | ranges::to<std::vector<std::string>>())
{
auto&& names = sourceContract | ranges::views::split(':') | ranges::to<vector<string>>();
auto&& names = sourceContract | ranges::views::split(':') | ranges::to<std::vector<std::string>>();
if (names.size() != 2 || names.at(0).empty() || names.at(1).empty())
return {};
chosen[names.at(0)].insert(names.at(1));
@ -131,7 +130,7 @@ std::optional<ModelCheckerContracts> ModelCheckerContracts::fromString(string co
return ModelCheckerContracts{chosen};
}
std::optional<ModelCheckerExtCalls> ModelCheckerExtCalls::fromString(string const& _mode)
std::optional<ModelCheckerExtCalls> ModelCheckerExtCalls::fromString(std::string const& _mode)
{
if (_mode == "untrusted")
return ModelCheckerExtCalls{Mode::UNTRUSTED};

View File

@ -31,27 +31,26 @@
#include <range/v3/view.hpp>
#include <utility>
using namespace std;
using boost::algorithm::starts_with;
using namespace solidity;
using namespace solidity::smtutil;
using namespace solidity::frontend;
using namespace solidity::frontend::smt;
map<string, Predicate> Predicate::m_predicates;
std::map<std::string, Predicate> Predicate::m_predicates;
Predicate const* Predicate::create(
SortPointer _sort,
string _name,
std::string _name,
PredicateType _type,
EncodingContext& _context,
ASTNode const* _node,
ContractDefinition const* _contractContext,
vector<ScopeOpener const*> _scopeStack
std::vector<ScopeOpener const*> _scopeStack
)
{
smt::SymbolicFunctionVariable predicate{_sort, std::move(_name), _context};
string functorName = predicate.currentName();
std::string functorName = predicate.currentName();
solAssert(!m_predicates.count(functorName), "");
return &m_predicates.emplace(
std::piecewise_construct,
@ -65,7 +64,7 @@ Predicate::Predicate(
PredicateType _type,
ASTNode const* _node,
ContractDefinition const* _contractContext,
vector<ScopeOpener const*> _scopeStack
std::vector<ScopeOpener const*> _scopeStack
):
m_predicate(std::move(_predicate)),
m_type(_type),
@ -75,7 +74,7 @@ Predicate::Predicate(
{
}
Predicate const* Predicate::predicate(string const& _name)
Predicate const* Predicate::predicate(std::string const& _name)
{
return &m_predicates.at(_name);
}
@ -85,7 +84,7 @@ void Predicate::reset()
m_predicates.clear();
}
smtutil::Expression Predicate::operator()(vector<smtutil::Expression> const& _args) const
smtutil::Expression Predicate::operator()(std::vector<smtutil::Expression> const& _args) const
{
return m_predicate(_args);
}
@ -149,12 +148,12 @@ VariableDeclaration const* Predicate::programVariable() const
return dynamic_cast<VariableDeclaration const*>(m_node);
}
optional<vector<VariableDeclaration const*>> Predicate::stateVariables() const
std::optional<std::vector<VariableDeclaration const*>> Predicate::stateVariables() const
{
if (m_contractContext)
return SMTEncoder::stateVariablesIncludingInheritedAndPrivate(*m_contractContext);
return nullopt;
return std::nullopt;
}
bool Predicate::isSummary() const
@ -211,8 +210,8 @@ bool Predicate::isNondetInterface() const
return m_type == PredicateType::NondetInterface;
}
string Predicate::formatSummaryCall(
vector<smtutil::Expression> const& _args,
std::string Predicate::formatSummaryCall(
std::vector<smtutil::Expression> const& _args,
langutil::CharStreamProvider const& _charStreamProvider,
bool _appendTxVars
) const
@ -225,7 +224,7 @@ string Predicate::formatSummaryCall(
if (auto funCall = programFunctionCall())
{
if (funCall->location().hasText())
return string(_charStreamProvider.charStream(*funCall->location().sourceName).text(funCall->location()));
return std::string(_charStreamProvider.charStream(*funCall->location().sourceName).text(funCall->location()));
else
return {};
}
@ -233,11 +232,11 @@ string Predicate::formatSummaryCall(
/// The signature of a function summary predicate is: summary(error, this, abiFunctions, cryptoFunctions, txData, preBlockChainState, preStateVars, preInputVars, postBlockchainState, postStateVars, postInputVars, outputVars).
/// Here we are interested in preInputVars to format the function call.
string txModel;
std::string txModel;
if (_appendTxVars)
{
set<string> txVars;
std::set<std::string> txVars;
if (isFunctionSummary())
{
solAssert(programFunction(), "");
@ -276,7 +275,7 @@ string Predicate::formatSummaryCall(
return true;
}
set<string> txVars;
std::set<std::string> txVars;
} txVarsVisitor;
if (auto fun = programFunction())
@ -287,7 +286,7 @@ string Predicate::formatSummaryCall(
// Here we are interested in txData from the summary predicate.
auto txValues = readTxVars(_args.at(4));
vector<string> values;
std::vector<std::string> values;
for (auto const& _var: txVars)
if (auto v = txValues.at(_var))
values.push_back(_var + ": " + *v);
@ -309,8 +308,8 @@ string Predicate::formatSummaryCall(
solAssert(first >= _args.begin() && first <= _args.end(), "");
solAssert(last >= _args.begin() && last <= _args.end(), "");
auto inTypes = SMTEncoder::replaceUserTypes(FunctionType(*fun).parameterTypes());
vector<optional<string>> functionArgsCex = formatExpressions(vector<smtutil::Expression>(first, last), inTypes);
vector<string> functionArgs;
std::vector<std::optional<std::string>> functionArgsCex = formatExpressions(std::vector<smtutil::Expression>(first, last), inTypes);
std::vector<std::string> functionArgs;
auto const& params = fun->parameters();
solAssert(params.size() == functionArgsCex.size(), "");
@ -320,12 +319,12 @@ string Predicate::formatSummaryCall(
else
functionArgs.emplace_back(params[i]->name());
string fName = fun->isConstructor() ? "constructor" :
std::string fName = fun->isConstructor() ? "constructor" :
fun->isFallback() ? "fallback" :
fun->isReceive() ? "receive" :
fun->name();
string prefix;
std::string prefix;
if (fun->isFree())
prefix = !fun->sourceUnitName().empty() ? (fun->sourceUnitName() + ":") : "";
else
@ -336,7 +335,7 @@ string Predicate::formatSummaryCall(
return prefix + fName + "(" + boost::algorithm::join(functionArgs, ", ") + ")" + txModel;
}
vector<optional<string>> Predicate::summaryStateValues(vector<smtutil::Expression> const& _args) const
std::vector<std::optional<std::string>> Predicate::summaryStateValues(std::vector<smtutil::Expression> const& _args) const
{
/// The signature of a function summary predicate is: summary(error, this, abiFunctions, cryptoFunctions, txData, preBlockchainState, preStateVars, preInputVars, postBlockchainState, postStateVars, postInputVars, outputVars).
/// The signature of the summary predicate of a contract without constructor is: summary(error, this, abiFunctions, cryptoFunctions, txData, preBlockchainState, postBlockchainState, preStateVars, postStateVars).
@ -344,8 +343,8 @@ vector<optional<string>> Predicate::summaryStateValues(vector<smtutil::Expressio
auto stateVars = stateVariables();
solAssert(stateVars.has_value(), "");
vector<smtutil::Expression>::const_iterator stateFirst;
vector<smtutil::Expression>::const_iterator stateLast;
std::vector<smtutil::Expression>::const_iterator stateFirst;
std::vector<smtutil::Expression>::const_iterator stateLast;
if (auto const* function = programFunction())
{
stateFirst = _args.begin() + 6 + static_cast<int>(stateVars->size()) + static_cast<int>(function->parameters().size()) + 1;
@ -364,13 +363,13 @@ vector<optional<string>> Predicate::summaryStateValues(vector<smtutil::Expressio
solAssert(stateFirst >= _args.begin() && stateFirst <= _args.end(), "");
solAssert(stateLast >= _args.begin() && stateLast <= _args.end(), "");
vector<smtutil::Expression> stateArgs(stateFirst, stateLast);
std::vector<smtutil::Expression> stateArgs(stateFirst, stateLast);
solAssert(stateArgs.size() == stateVars->size(), "");
auto stateTypes = util::applyMap(*stateVars, [&](auto const& _var) { return _var->type(); });
return formatExpressions(stateArgs, stateTypes);
}
vector<optional<string>> Predicate::summaryPostInputValues(vector<smtutil::Expression> const& _args) const
std::vector<std::optional<std::string>> Predicate::summaryPostInputValues(std::vector<smtutil::Expression> const& _args) const
{
/// The signature of a function summary predicate is: summary(error, this, abiFunctions, cryptoFunctions, txData, preBlockchainState, preStateVars, preInputVars, postBlockchainState, postStateVars, postInputVars, outputVars).
/// Here we are interested in postInputVars.
@ -388,13 +387,13 @@ vector<optional<string>> Predicate::summaryPostInputValues(vector<smtutil::Expre
solAssert(first >= _args.begin() && first <= _args.end(), "");
solAssert(last >= _args.begin() && last <= _args.end(), "");
vector<smtutil::Expression> inValues(first, last);
std::vector<smtutil::Expression> inValues(first, last);
solAssert(inValues.size() == inParams.size(), "");
auto inTypes = SMTEncoder::replaceUserTypes(FunctionType(*function).parameterTypes());
return formatExpressions(inValues, inTypes);
}
vector<optional<string>> Predicate::summaryPostOutputValues(vector<smtutil::Expression> const& _args) const
std::vector<std::optional<std::string>> Predicate::summaryPostOutputValues(std::vector<smtutil::Expression> const& _args) const
{
/// The signature of a function summary predicate is: summary(error, this, abiFunctions, cryptoFunctions, txData, preBlockchainState, preStateVars, preInputVars, postBlockchainState, postStateVars, postInputVars, outputVars).
/// Here we are interested in outputVars.
@ -410,13 +409,13 @@ vector<optional<string>> Predicate::summaryPostOutputValues(vector<smtutil::Expr
solAssert(first >= _args.begin() && first <= _args.end(), "");
vector<smtutil::Expression> outValues(first, _args.end());
std::vector<smtutil::Expression> outValues(first, _args.end());
solAssert(outValues.size() == function->returnParameters().size(), "");
auto outTypes = SMTEncoder::replaceUserTypes(FunctionType(*function).returnParameterTypes());
return formatExpressions(outValues, outTypes);
}
pair<vector<optional<string>>, vector<VariableDeclaration const*>> Predicate::localVariableValues(vector<smtutil::Expression> const& _args) const
std::pair<std::vector<std::optional<std::string>>, std::vector<VariableDeclaration const*>> Predicate::localVariableValues(std::vector<smtutil::Expression> const& _args) const
{
/// The signature of a local block predicate is:
/// block(error, this, abiFunctions, cryptoFunctions, txData, preBlockchainState, preStateVars, preInputVars, postBlockchainState, postStateVars, postInputVars, outputVars, localVars).
@ -426,7 +425,7 @@ pair<vector<optional<string>>, vector<VariableDeclaration const*>> Predicate::lo
auto const& localVars = SMTEncoder::localVariablesIncludingModifiers(*function, m_contractContext);
auto first = _args.end() - static_cast<int>(localVars.size());
vector<smtutil::Expression> outValues(first, _args.end());
std::vector<smtutil::Expression> outValues(first, _args.end());
auto mask = util::applyMap(
localVars,
@ -442,10 +441,10 @@ pair<vector<optional<string>>, vector<VariableDeclaration const*>> Predicate::lo
return {formatExpressions(outValuesInScope, outTypes), localVarsInScope};
}
map<string, string> Predicate::expressionSubstitution(smtutil::Expression const& _predExpr) const
std::map<std::string, std::string> Predicate::expressionSubstitution(smtutil::Expression const& _predExpr) const
{
map<string, string> subst;
string predName = functor().name;
std::map<std::string, std::string> subst;
std::string predName = functor().name;
solAssert(contextContract(), "");
auto const& stateVars = SMTEncoder::stateVariablesIncludingInheritedAndPrivate(*contextContract());
@ -486,16 +485,16 @@ map<string, string> Predicate::expressionSubstitution(smtutil::Expression const&
return subst;
}
vector<optional<string>> Predicate::formatExpressions(vector<smtutil::Expression> const& _exprs, vector<Type const*> const& _types) const
std::vector<std::optional<std::string>> Predicate::formatExpressions(std::vector<smtutil::Expression> const& _exprs, std::vector<Type const*> const& _types) const
{
solAssert(_exprs.size() == _types.size(), "");
vector<optional<string>> strExprs;
std::vector<std::optional<std::string>> strExprs;
for (unsigned i = 0; i < _exprs.size(); ++i)
strExprs.push_back(expressionToString(_exprs.at(i), _types.at(i)));
return strExprs;
}
optional<string> Predicate::expressionToString(smtutil::Expression const& _expr, Type const* _type) const
std::optional<std::string> Predicate::expressionToString(smtutil::Expression const& _expr, Type const* _type) const
{
if (smt::isNumber(*_type))
{
@ -514,10 +513,10 @@ optional<string> Predicate::expressionToString(smtutil::Expression const& _expr,
// For some reason the code below returns "0x" for "0".
return util::toHex(toCompactBigEndian(bigint(_expr.name)), util::HexPrefix::Add, util::HexCase::Lower);
}
catch (out_of_range const&)
catch (std::out_of_range const&)
{
}
catch (invalid_argument const&)
catch (std::invalid_argument const&)
{
}
}
@ -550,11 +549,11 @@ optional<string> Predicate::expressionToString(smtutil::Expression const& _expr,
{
length = stoul(_expr.arguments.at(1).name);
}
catch(out_of_range const&)
catch(std::out_of_range const&)
{
return {};
}
catch(invalid_argument const&)
catch(std::invalid_argument const&)
{
return {};
}
@ -567,12 +566,12 @@ optional<string> Predicate::expressionToString(smtutil::Expression const& _expr,
return {};
try
{
vector<string> array(length);
std::vector<std::string> array(length);
if (!fillArray(_expr.arguments.at(0), array, arrayType))
return {};
return "[" + boost::algorithm::join(array, ", ") + "]";
}
catch (bad_alloc const&)
catch (std::bad_alloc const&)
{
// Solver gave a concrete array but length is too large.
}
@ -585,10 +584,10 @@ optional<string> Predicate::expressionToString(smtutil::Expression const& _expr,
auto members = structType.structDefinition().members();
solAssert(tupleSort.components.size() == members.size(), "");
solAssert(_expr.arguments.size() == members.size(), "");
vector<string> elements;
std::vector<std::string> elements;
for (unsigned i = 0; i < members.size(); ++i)
{
optional<string> elementStr = expressionToString(_expr.arguments.at(i), members[i]->type());
std::optional<std::string> elementStr = expressionToString(_expr.arguments.at(i), members[i]->type());
elements.push_back(members[i]->name() + (elementStr.has_value() ? ": " + elementStr.value() : ""));
}
return "{" + boost::algorithm::join(elements, ", ") + "}";
@ -597,13 +596,13 @@ optional<string> Predicate::expressionToString(smtutil::Expression const& _expr,
return {};
}
bool Predicate::fillArray(smtutil::Expression const& _expr, vector<string>& _array, ArrayType const& _type) const
bool Predicate::fillArray(smtutil::Expression const& _expr, std::vector<std::string>& _array, ArrayType const& _type) const
{
// Base case
if (_expr.name == "const_array")
{
auto length = _array.size();
optional<string> elemStr = expressionToString(_expr.arguments.at(1), _type.baseType());
std::optional<std::string> elemStr = expressionToString(_expr.arguments.at(1), _type.baseType());
if (!elemStr)
return false;
_array.clear();
@ -616,7 +615,7 @@ bool Predicate::fillArray(smtutil::Expression const& _expr, vector<string>& _arr
{
if (!fillArray(_expr.arguments.at(0), _array, _type))
return false;
optional<string> indexStr = expressionToString(_expr.arguments.at(1), TypeProvider::uint256());
std::optional<std::string> indexStr = expressionToString(_expr.arguments.at(1), TypeProvider::uint256());
if (!indexStr)
return false;
// Sometimes the solver assigns huge lengths that are not related,
@ -626,15 +625,15 @@ bool Predicate::fillArray(smtutil::Expression const& _expr, vector<string>& _arr
{
index = stoul(*indexStr);
}
catch (out_of_range const&)
catch (std::out_of_range const&)
{
return true;
}
catch (invalid_argument const&)
catch (std::invalid_argument const&)
{
return true;
}
optional<string> elemStr = expressionToString(_expr.arguments.at(2), _type.baseType());
std::optional<std::string> elemStr = expressionToString(_expr.arguments.at(2), _type.baseType());
if (!elemStr)
return false;
if (index < _array.size())
@ -652,9 +651,9 @@ bool Predicate::fillArray(smtutil::Expression const& _expr, vector<string>& _arr
solAssert(false, "");
}
map<string, optional<string>> Predicate::readTxVars(smtutil::Expression const& _tx) const
std::map<std::string, std::optional<std::string>> Predicate::readTxVars(smtutil::Expression const& _tx) const
{
map<string, Type const*> const txVars{
std::map<std::string, Type const*> const txVars{
{"block.basefee", TypeProvider::uint256()},
{"block.chainid", TypeProvider::uint256()},
{"block.coinbase", TypeProvider::address()},
@ -670,7 +669,7 @@ map<string, optional<string>> Predicate::readTxVars(smtutil::Expression const& _
{"tx.gasprice", TypeProvider::uint256()},
{"tx.origin", TypeProvider::address()}
};
map<string, optional<string>> vars;
std::map<std::string, std::optional<std::string>> vars;
for (auto&& [i, v]: txVars | ranges::views::enumerate)
vars.emplace(v.first, expressionToString(_tx.arguments.at(i), v.second));
return vars;

View File

@ -21,7 +21,6 @@
#include <libsolidity/formal/EncodingContext.h>
#include <libsolidity/formal/SMTEncoder.h>
using namespace std;
using namespace solidity::util;
using namespace solidity::smtutil;
@ -30,14 +29,14 @@ namespace solidity::frontend::smt
smtutil::Expression interfacePre(Predicate const& _pred, ContractDefinition const& _contract, EncodingContext& _context)
{
auto& state = _context.state();
vector<smtutil::Expression> stateExprs{state.thisAddress(0), state.abi(0), state.crypto(0), state.state(0)};
std::vector<smtutil::Expression> stateExprs{state.thisAddress(0), state.abi(0), state.crypto(0), state.state(0)};
return _pred(stateExprs + initialStateVariables(_contract, _context));
}
smtutil::Expression interface(Predicate const& _pred, ContractDefinition const& _contract, EncodingContext& _context)
{
auto const& state = _context.state();
vector<smtutil::Expression> stateExprs{state.thisAddress(0), state.abi(0), state.crypto(0), state.state()};
std::vector<smtutil::Expression> stateExprs{state.thisAddress(0), state.abi(0), state.crypto(0), state.state()};
return _pred(stateExprs + currentStateVariables(_contract, _context));
}
@ -49,12 +48,12 @@ smtutil::Expression nondetInterface(
unsigned _postIdx)
{
auto const& state = _context.state();
vector<smtutil::Expression> stateExprs{state.errorFlag().currentValue(), state.thisAddress(), state.abi(), state.crypto()};
std::vector<smtutil::Expression> stateExprs{state.errorFlag().currentValue(), state.thisAddress(), state.abi(), state.crypto()};
return _pred(
stateExprs +
vector<smtutil::Expression>{_context.state().state(_preIdx)} +
std::vector<smtutil::Expression>{_context.state().state(_preIdx)} +
stateVariablesAtIndex(_preIdx, _contract, _context) +
vector<smtutil::Expression>{_context.state().state(_postIdx)} +
std::vector<smtutil::Expression>{_context.state().state(_postIdx)} +
stateVariablesAtIndex(_postIdx, _contract, _context)
);
}
@ -66,7 +65,7 @@ smtutil::Expression constructor(Predicate const& _pred, EncodingContext& _contex
return _pred(currentFunctionVariablesForDefinition(*constructor, &contract, _context));
auto& state = _context.state();
vector<smtutil::Expression> stateExprs{state.errorFlag().currentValue(), state.thisAddress(0), state.abi(0), state.crypto(0), state.tx(0), state.state(0), state.state()};
std::vector<smtutil::Expression> stateExprs{state.errorFlag().currentValue(), state.thisAddress(0), state.abi(0), state.crypto(0), state.tx(0), state.state(0), state.state()};
return _pred(stateExprs + initialStateVariables(contract, _context) + currentStateVariables(contract, _context));
}
@ -77,9 +76,9 @@ smtutil::Expression constructorCall(Predicate const& _pred, EncodingContext& _co
return _pred(currentFunctionVariablesForCall(*constructor, &contract, _context, _internal));
auto& state = _context.state();
vector<smtutil::Expression> stateExprs{state.errorFlag().currentValue(), _internal ? state.thisAddress(0) : state.thisAddress(), state.abi(0), state.crypto(0), _internal ? state.tx(0) : state.tx(), state.state()};
std::vector<smtutil::Expression> stateExprs{state.errorFlag().currentValue(), _internal ? state.thisAddress(0) : state.thisAddress(), state.abi(0), state.crypto(0), _internal ? state.tx(0) : state.tx(), state.state()};
state.newState();
stateExprs += vector<smtutil::Expression>{state.state()};
stateExprs += std::vector<smtutil::Expression>{state.state()};
stateExprs += currentStateVariables(contract, _context);
stateExprs += newStateVariables(contract, _context);
return _pred(stateExprs);
@ -117,12 +116,12 @@ smtutil::Expression functionBlock(
/// Helpers
vector<smtutil::Expression> initialStateVariables(ContractDefinition const& _contract, EncodingContext& _context)
std::vector<smtutil::Expression> initialStateVariables(ContractDefinition const& _contract, EncodingContext& _context)
{
return stateVariablesAtIndex(0, _contract, _context);
}
vector<smtutil::Expression> stateVariablesAtIndex(unsigned _index, ContractDefinition const& _contract, EncodingContext& _context)
std::vector<smtutil::Expression> stateVariablesAtIndex(unsigned _index, ContractDefinition const& _contract, EncodingContext& _context)
{
return applyMap(
SMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract),
@ -130,7 +129,7 @@ vector<smtutil::Expression> stateVariablesAtIndex(unsigned _index, ContractDefin
);
}
vector<smtutil::Expression> currentStateVariables(ContractDefinition const& _contract, EncodingContext& _context)
std::vector<smtutil::Expression> currentStateVariables(ContractDefinition const& _contract, EncodingContext& _context)
{
return applyMap(
SMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract),
@ -138,7 +137,7 @@ vector<smtutil::Expression> currentStateVariables(ContractDefinition const& _con
);
}
vector<smtutil::Expression> newStateVariables(ContractDefinition const& _contract, EncodingContext& _context)
std::vector<smtutil::Expression> newStateVariables(ContractDefinition const& _contract, EncodingContext& _context)
{
return applyMap(
SMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract),
@ -146,24 +145,24 @@ vector<smtutil::Expression> newStateVariables(ContractDefinition const& _contrac
);
}
vector<smtutil::Expression> currentFunctionVariablesForDefinition(
std::vector<smtutil::Expression> currentFunctionVariablesForDefinition(
FunctionDefinition const& _function,
ContractDefinition const* _contract,
EncodingContext& _context
)
{
auto& state = _context.state();
vector<smtutil::Expression> exprs{state.errorFlag().currentValue(), state.thisAddress(0), state.abi(0), state.crypto(0), state.tx(0), state.state(0)};
exprs += _contract ? initialStateVariables(*_contract, _context) : vector<smtutil::Expression>{};
std::vector<smtutil::Expression> exprs{state.errorFlag().currentValue(), state.thisAddress(0), state.abi(0), state.crypto(0), state.tx(0), state.state(0)};
exprs += _contract ? initialStateVariables(*_contract, _context) : std::vector<smtutil::Expression>{};
exprs += applyMap(_function.parameters(), [&](auto _var) { return _context.variable(*_var)->valueAtIndex(0); });
exprs += vector<smtutil::Expression>{state.state()};
exprs += _contract ? currentStateVariables(*_contract, _context) : vector<smtutil::Expression>{};
exprs += std::vector<smtutil::Expression>{state.state()};
exprs += _contract ? currentStateVariables(*_contract, _context) : std::vector<smtutil::Expression>{};
exprs += applyMap(_function.parameters(), [&](auto _var) { return _context.variable(*_var)->currentValue(); });
exprs += applyMap(_function.returnParameters(), [&](auto _var) { return _context.variable(*_var)->currentValue(); });
return exprs;
}
vector<smtutil::Expression> currentFunctionVariablesForCall(
std::vector<smtutil::Expression> currentFunctionVariablesForCall(
FunctionDefinition const& _function,
ContractDefinition const* _contract,
EncodingContext& _context,
@ -171,20 +170,20 @@ vector<smtutil::Expression> currentFunctionVariablesForCall(
)
{
auto& state = _context.state();
vector<smtutil::Expression> exprs{state.errorFlag().currentValue(), _internal ? state.thisAddress(0) : state.thisAddress(), state.abi(0), state.crypto(0), _internal ? state.tx(0) : state.tx(), state.state()};
exprs += _contract ? currentStateVariables(*_contract, _context) : vector<smtutil::Expression>{};
std::vector<smtutil::Expression> exprs{state.errorFlag().currentValue(), _internal ? state.thisAddress(0) : state.thisAddress(), state.abi(0), state.crypto(0), _internal ? state.tx(0) : state.tx(), state.state()};
exprs += _contract ? currentStateVariables(*_contract, _context) : std::vector<smtutil::Expression>{};
exprs += applyMap(_function.parameters(), [&](auto _var) { return _context.variable(*_var)->currentValue(); });
state.newState();
exprs += vector<smtutil::Expression>{state.state()};
exprs += _contract ? newStateVariables(*_contract, _context) : vector<smtutil::Expression>{};
exprs += std::vector<smtutil::Expression>{state.state()};
exprs += _contract ? newStateVariables(*_contract, _context) : std::vector<smtutil::Expression>{};
exprs += applyMap(_function.parameters(), [&](auto _var) { return _context.variable(*_var)->increaseIndex(); });
exprs += applyMap(_function.returnParameters(), [&](auto _var) { return _context.variable(*_var)->currentValue(); });
return exprs;
}
vector<smtutil::Expression> currentBlockVariables(FunctionDefinition const& _function, ContractDefinition const* _contract, EncodingContext& _context)
std::vector<smtutil::Expression> currentBlockVariables(FunctionDefinition const& _function, ContractDefinition const* _contract, EncodingContext& _context)
{
return currentFunctionVariablesForDefinition(_function, _contract, _context) +
applyMap(

View File

@ -21,7 +21,6 @@
#include <libsolidity/formal/SMTEncoder.h>
#include <libsolidity/formal/SymbolicTypes.h>
using namespace std;
using namespace solidity::util;
using namespace solidity::smtutil;
@ -30,8 +29,8 @@ namespace solidity::frontend::smt
SortPointer interfaceSort(ContractDefinition const& _contract, SymbolicState& _state)
{
return make_shared<FunctionSort>(
vector<SortPointer>{_state.thisAddressSort(), _state.abiSort(), _state.cryptoSort(), _state.stateSort()} + stateSorts(_contract),
return std::make_shared<FunctionSort>(
std::vector<SortPointer>{_state.thisAddressSort(), _state.abiSort(), _state.cryptoSort(), _state.stateSort()} + stateSorts(_contract),
SortProvider::boolSort
);
}
@ -39,9 +38,9 @@ SortPointer interfaceSort(ContractDefinition const& _contract, SymbolicState& _s
SortPointer nondetInterfaceSort(ContractDefinition const& _contract, SymbolicState& _state)
{
auto varSorts = stateSorts(_contract);
vector<SortPointer> stateSort{_state.stateSort()};
return make_shared<FunctionSort>(
vector<SortPointer>{_state.errorFlagSort(), _state.thisAddressSort(), _state.abiSort(), _state.cryptoSort()} +
std::vector<SortPointer> stateSort{_state.stateSort()};
return std::make_shared<FunctionSort>(
std::vector<SortPointer>{_state.errorFlagSort(), _state.thisAddressSort(), _state.abiSort(), _state.cryptoSort()} +
stateSort +
varSorts +
stateSort +
@ -56,9 +55,9 @@ SortPointer constructorSort(ContractDefinition const& _contract, SymbolicState&
return functionSort(*constructor, &_contract, _state);
auto varSorts = stateSorts(_contract);
vector<SortPointer> stateSort{_state.stateSort()};
return make_shared<FunctionSort>(
vector<SortPointer>{_state.errorFlagSort(), _state.thisAddressSort(), _state.abiSort(), _state.cryptoSort(), _state.txSort(), _state.stateSort(), _state.stateSort()} + varSorts + varSorts,
std::vector<SortPointer> stateSort{_state.stateSort()};
return std::make_shared<FunctionSort>(
std::vector<SortPointer>{_state.errorFlagSort(), _state.thisAddressSort(), _state.abiSort(), _state.cryptoSort(), _state.txSort(), _state.stateSort(), _state.stateSort()} + varSorts + varSorts,
SortProvider::boolSort
);
}
@ -66,14 +65,14 @@ SortPointer constructorSort(ContractDefinition const& _contract, SymbolicState&
SortPointer functionSort(FunctionDefinition const& _function, ContractDefinition const* _contract, SymbolicState& _state)
{
auto smtSort = [](auto _var) { return smt::smtSortAbstractFunction(*_var->type()); };
auto varSorts = _contract ? stateSorts(*_contract) : vector<SortPointer>{};
auto varSorts = _contract ? stateSorts(*_contract) : std::vector<SortPointer>{};
auto inputSorts = applyMap(_function.parameters(), smtSort);
auto outputSorts = applyMap(_function.returnParameters(), smtSort);
return make_shared<FunctionSort>(
vector<SortPointer>{_state.errorFlagSort(), _state.thisAddressSort(), _state.abiSort(), _state.cryptoSort(), _state.txSort(), _state.stateSort()} +
return std::make_shared<FunctionSort>(
std::vector<SortPointer>{_state.errorFlagSort(), _state.thisAddressSort(), _state.abiSort(), _state.cryptoSort(), _state.txSort(), _state.stateSort()} +
varSorts +
inputSorts +
vector<SortPointer>{_state.stateSort()} +
std::vector<SortPointer>{_state.stateSort()} +
varSorts +
inputSorts +
outputSorts,
@ -83,11 +82,11 @@ SortPointer functionSort(FunctionDefinition const& _function, ContractDefinition
SortPointer functionBodySort(FunctionDefinition const& _function, ContractDefinition const* _contract, SymbolicState& _state)
{
auto fSort = dynamic_pointer_cast<FunctionSort>(functionSort(_function, _contract, _state));
auto fSort = std::dynamic_pointer_cast<FunctionSort>(functionSort(_function, _contract, _state));
solAssert(fSort, "");
auto smtSort = [](auto _var) { return smt::smtSortAbstractFunction(*_var->type()); };
return make_shared<FunctionSort>(
return std::make_shared<FunctionSort>(
fSort->domain + applyMap(SMTEncoder::localVariablesIncludingModifiers(_function, _contract), smtSort),
SortProvider::boolSort
);
@ -95,15 +94,15 @@ SortPointer functionBodySort(FunctionDefinition const& _function, ContractDefini
SortPointer arity0FunctionSort()
{
return make_shared<FunctionSort>(
vector<SortPointer>(),
return std::make_shared<FunctionSort>(
std::vector<SortPointer>(),
SortProvider::boolSort
);
}
/// Helpers
vector<SortPointer> stateSorts(ContractDefinition const& _contract)
std::vector<SortPointer> stateSorts(ContractDefinition const& _contract)
{
return applyMap(
SMTEncoder::stateVariablesIncludingInheritedAndPrivate(_contract),

View File

@ -40,11 +40,11 @@
#include <limits>
#include <deque>
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::langutil;
using namespace solidity::frontend;
using namespace std::string_literals;
SMTEncoder::SMTEncoder(
smt::EncodingContext& _context,
@ -72,8 +72,8 @@ bool SMTEncoder::visit(ContractDefinition const& _contract)
for (auto const& node: _contract.subNodes())
if (
!dynamic_pointer_cast<FunctionDefinition>(node) &&
!dynamic_pointer_cast<VariableDeclaration>(node)
!std::dynamic_pointer_cast<FunctionDefinition>(node) &&
!std::dynamic_pointer_cast<VariableDeclaration>(node)
)
node->accept(*this);
@ -198,7 +198,7 @@ void SMTEncoder::inlineModifierInvocation(ModifierInvocation const* _invocation,
solAssert(_invocation, "");
_invocation->accept(*this);
vector<smtutil::Expression> args;
std::vector<smtutil::Expression> args;
if (auto const* arguments = _invocation->arguments())
{
auto const& modifierParams = _definition->parameters();
@ -314,8 +314,8 @@ bool SMTEncoder::visit(InlineAssembly const& _inlineAsm)
this->operator()(_inlineAsm.operations());
}
map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> const& externalReferences;
set<VariableDeclaration const*> assignedVars;
std::map<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> const& externalReferences;
std::set<VariableDeclaration const*> assignedVars;
using yul::ASTWalker::operator();
void operator()(yul::Assignment const& _assignment)
@ -425,14 +425,14 @@ void SMTEncoder::endVisit(TupleExpression const& _tuple)
if (_tuple.isInlineArray())
{
// Add constraints for the length and values as it is known.
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(_tuple));
auto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(_tuple));
solAssert(symbArray, "");
addArrayLiteralAssertions(*symbArray, applyMap(_tuple.components(), [&](auto const& c) { return expr(*c); }));
}
else
{
auto values = applyMap(_tuple.components(), [this](auto const& component) -> optional<smtutil::Expression> {
auto values = applyMap(_tuple.components(), [this](auto const& component) -> std::optional<smtutil::Expression> {
if (component)
{
if (!m_context.knownExpression(*component))
@ -816,19 +816,19 @@ void SMTEncoder::visitABIFunction(FunctionCall const& _funCall)
defineExpr(_funCall, smt::zeroValue(TypeProvider::bytesMemory()));
return;
}
vector<smtutil::Expression> symbArgs;
std::vector<smtutil::Expression> symbArgs;
for (unsigned i = 0; i < argsActualLength; ++i)
if (args.at(i))
symbArgs.emplace_back(expr(*args.at(i), inTypes.at(i)));
optional<smtutil::Expression> arg;
std::optional<smtutil::Expression> arg;
if (inTypes.size() == 1)
arg = expr(*args.at(0), inTypes.at(0));
else
{
auto inputSort = dynamic_cast<smtutil::ArraySort&>(*symbFunction.sort).domain;
arg = smtutil::Expression::tuple_constructor(
smtutil::Expression(make_shared<smtutil::SortSort>(inputSort), ""),
smtutil::Expression(std::make_shared<smtutil::SortSort>(inputSort), ""),
symbArgs
);
}
@ -838,7 +838,7 @@ void SMTEncoder::visitABIFunction(FunctionCall const& _funCall)
defineExpr(_funCall, out);
else
{
auto symbTuple = dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(_funCall));
auto symbTuple = std::dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(_funCall));
solAssert(symbTuple, "");
solAssert(symbTuple->components().size() == outTypes.size(), "");
solAssert(out.sort->kind == smtutil::Kind::Tuple, "");
@ -854,7 +854,7 @@ void SMTEncoder::visitCryptoFunction(FunctionCall const& _funCall)
auto const& funType = dynamic_cast<FunctionType const&>(*_funCall.expression().annotation().type);
auto kind = funType.kind();
auto arg0 = expr(*_funCall.arguments().at(0));
optional<smtutil::Expression> result;
std::optional<smtutil::Expression> result;
if (kind == FunctionType::Kind::KECCAK256)
result = smtutil::Expression::select(state().cryptoFunction("keccak256"), arg0);
else if (kind == FunctionType::Kind::SHA256)
@ -870,7 +870,7 @@ void SMTEncoder::visitCryptoFunction(FunctionCall const& _funCall)
auto arg3 = expr(*_funCall.arguments().at(3));
auto inputSort = dynamic_cast<smtutil::ArraySort&>(*e.sort).domain;
auto ecrecoverInput = smtutil::Expression::tuple_constructor(
smtutil::Expression(make_shared<smtutil::SortSort>(inputSort), ""),
smtutil::Expression(std::make_shared<smtutil::SortSort>(inputSort), ""),
{arg0, arg1, arg2, arg3}
);
result = smtutil::Expression::select(e, ecrecoverInput);
@ -883,7 +883,7 @@ void SMTEncoder::visitCryptoFunction(FunctionCall const& _funCall)
void SMTEncoder::visitGasLeft(FunctionCall const& _funCall)
{
string gasLeft = "gasleft";
std::string gasLeft = "gasleft";
// We increase the variable index since gasleft changes
// inside a tx.
defineGlobalVariable(gasLeft, _funCall, true);
@ -930,7 +930,7 @@ void SMTEncoder::visitObjectCreation(FunctionCall const& _funCall)
smtutil::Expression arraySize = expr(*args.front());
setSymbolicUnknownValue(arraySize, TypeProvider::uint256(), m_context);
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(_funCall));
auto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(_funCall));
solAssert(symbArray, "");
smt::setSymbolicZeroValue(*symbArray, m_context);
auto zeroElements = symbArray->elements();
@ -1004,9 +1004,9 @@ bool isReturnedFromStructGetter(Type const* _type)
return true;
}
vector<string> structGetterReturnedMembers(StructType const& _structType)
std::vector<std::string> structGetterReturnedMembers(StructType const& _structType)
{
vector<string> returnedMembers;
std::vector<std::string> returnedMembers;
for (auto const& member: _structType.nativeMembers(nullptr))
if (isReturnedFromStructGetter(member.type))
returnedMembers.push_back(member.name);
@ -1023,7 +1023,7 @@ void SMTEncoder::visitPublicGetter(FunctionCall const& _funCall)
auto paramExpectedTypes = replaceUserTypes(FunctionType(*var).parameterTypes());
auto actualArguments = _funCall.arguments();
solAssert(actualArguments.size() == paramExpectedTypes.size(), "");
deque<smtutil::Expression> symbArguments;
std::deque<smtutil::Expression> symbArguments;
for (unsigned i = 0; i < paramExpectedTypes.size(); ++i)
symbArguments.push_back(expr(*actualArguments[i], paramExpectedTypes[i]));
@ -1063,11 +1063,11 @@ void SMTEncoder::visitPublicGetter(FunctionCall const& _funCall)
case Type::Category::Struct:
{
solAssert(symbArguments.empty(), "");
smt::SymbolicStructVariable structVar(dynamic_cast<StructType const*>(type), "struct_temp_" + to_string(_funCall.id()), m_context);
smt::SymbolicStructVariable structVar(dynamic_cast<StructType const*>(type), "struct_temp_" + std::to_string(_funCall.id()), m_context);
m_context.addAssertion(structVar.currentValue() == currentExpr);
auto returnedMembers = structGetterReturnedMembers(dynamic_cast<StructType const&>(*structVar.type()));
solAssert(!returnedMembers.empty(), "");
auto returnedValues = applyMap(returnedMembers, [&](string const& memberName) -> optional<smtutil::Expression> { return structVar.member(memberName); });
auto returnedValues = applyMap(returnedMembers, [&](std::string const& memberName) -> std::optional<smtutil::Expression> { return structVar.member(memberName); });
defineExpr(_funCall, returnedValues);
return;
}
@ -1118,7 +1118,7 @@ void SMTEncoder::visitTypeConversion(FunctionCall const& _funCall)
if (arrayType && arrayType->isByteArrayOrString() && smt::isFixedBytes(*funCallType))
{
auto array = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(*argument));
auto array = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(*argument));
bytesToFixedBytesAssertions(*array, _funCall);
return;
}
@ -1129,8 +1129,8 @@ void SMTEncoder::visitTypeConversion(FunctionCall const& _funCall)
unsigned castSize = funCallType->storageBytes();
bool castIsSigned = smt::isNumber(*funCallType) && smt::isSigned(funCallType);
bool argIsSigned = smt::isNumber(*argType) && smt::isSigned(argType);
optional<smtutil::Expression> symbMin;
optional<smtutil::Expression> symbMax;
std::optional<smtutil::Expression> symbMin;
std::optional<smtutil::Expression> symbMax;
if (smt::isNumber(*funCallType))
{
symbMin = smt::minValue(funCallType);
@ -1285,7 +1285,7 @@ void SMTEncoder::endVisit(Literal const& _literal)
createExpr(_literal);
// Add constraints for the length and values as it is known.
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(_literal));
auto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(_literal));
solAssert(symbArray, "");
addArrayLiteralAssertions(
@ -1299,7 +1299,7 @@ void SMTEncoder::endVisit(Literal const& _literal)
void SMTEncoder::addArrayLiteralAssertions(
smt::SymbolicArrayVariable& _symArray,
vector<smtutil::Expression> const& _elementValues
std::vector<smtutil::Expression> const& _elementValues
)
{
m_context.addAssertion(_symArray.length() == _elementValues.size());
@ -1314,7 +1314,7 @@ void SMTEncoder::bytesToFixedBytesAssertions(
{
auto const& fixed = dynamic_cast<FixedBytesType const&>(*_fixedBytes.annotation().type);
auto intType = TypeProvider::uint256();
string suffix = to_string(_fixedBytes.id()) + "_" + to_string(m_context.newUniqueId());
std::string suffix = std::to_string(_fixedBytes.id()) + "_" + std::to_string(m_context.newUniqueId());
smt::SymbolicIntVariable k(intType, intType, "k_" + suffix, m_context);
m_context.addAssertion(k.currentValue() == 0);
size_t n = fixed.numBytes();
@ -1333,7 +1333,7 @@ void SMTEncoder::endVisit(Return const& _return)
auto returnParams = m_callStack.back().first->returnParameters();
if (returnParams.size() > 1)
{
auto const& symbTuple = dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(*_return.expression()));
auto const& symbTuple = std::dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(*_return.expression()));
solAssert(symbTuple, "");
solAssert(symbTuple->components().size() == returnParams.size(), "");
@ -1428,7 +1428,7 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess)
else if (smt::isNonRecursiveStruct(*exprType))
{
memberExpr->accept(*this);
auto const& symbStruct = dynamic_pointer_cast<smt::SymbolicStructVariable>(m_context.expression(*memberExpr));
auto const& symbStruct = std::dynamic_pointer_cast<smt::SymbolicStructVariable>(m_context.expression(*memberExpr));
defineExpr(_memberAccess, symbStruct->member(_memberAccess.memberName()));
return false;
}
@ -1471,7 +1471,7 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess)
memberExpr->accept(*this);
if (_memberAccess.memberName() == "length")
{
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(*memberExpr));
auto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(*memberExpr));
solAssert(symbArray, "");
defineExpr(_memberAccess, symbArray->length());
m_uninterpretedTerms.insert(&_memberAccess);
@ -1554,7 +1554,7 @@ void SMTEncoder::endVisit(IndexAccess const& _indexAccess)
return;
}
shared_ptr<smt::SymbolicVariable> array;
std::shared_ptr<smt::SymbolicVariable> array;
if (auto const* id = dynamic_cast<Identifier const*>(&_indexAccess.baseExpression()))
{
auto varDecl = identifierToVariable(*id);
@ -1570,7 +1570,7 @@ void SMTEncoder::endVisit(IndexAccess const& _indexAccess)
array = m_context.expression(_indexAccess.baseExpression());
}
auto arrayVar = dynamic_pointer_cast<smt::SymbolicArrayVariable>(array);
auto arrayVar = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(array);
solAssert(arrayVar, "");
Type const* baseType = _indexAccess.baseExpression().annotation().type;
@ -1611,10 +1611,10 @@ void SMTEncoder::indexOrMemberAssignment(Expression const& _expr, smtutil::Expre
Type const* baseType = base.annotation().type;
auto indexExpr = expr(*indexAccess->indexExpression(), keyType(baseType));
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(base));
auto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(base));
solAssert(symbArray, "");
toStore = smtutil::Expression::tuple_constructor(
smtutil::Expression(make_shared<smtutil::SortSort>(smt::smtSort(*baseType)), baseType->toString(true)),
smtutil::Expression(std::make_shared<smtutil::SortSort>(smt::smtSort(*baseType)), baseType->toString(true)),
{smtutil::Expression::store(symbArray->elements(), indexExpr, toStore), symbArray->length()}
);
defineExpr(*indexAccess, smtutil::Expression::select(
@ -1650,7 +1650,7 @@ void SMTEncoder::indexOrMemberAssignment(Expression const& _expr, smtutil::Expre
break;
}
auto symbStruct = dynamic_pointer_cast<smt::SymbolicStructVariable>(m_context.expression(base));
auto symbStruct = std::dynamic_pointer_cast<smt::SymbolicStructVariable>(m_context.expression(base));
solAssert(symbStruct, "");
symbStruct->assignMember(memberAccess->memberName(), toStore);
toStore = symbStruct->currentValue();
@ -1688,7 +1688,7 @@ void SMTEncoder::arrayPush(FunctionCall const& _funCall)
{
auto memberAccess = dynamic_cast<MemberAccess const*>(&_funCall.expression());
solAssert(memberAccess, "");
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(memberAccess->expression()));
auto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(memberAccess->expression()));
solAssert(symbArray, "");
auto oldLength = symbArray->length();
m_context.addAssertion(oldLength >= 0);
@ -1722,7 +1722,7 @@ void SMTEncoder::arrayPop(FunctionCall const& _funCall)
{
auto memberAccess = dynamic_cast<MemberAccess const*>(cleanExpression(_funCall.expression()));
solAssert(memberAccess, "");
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(memberAccess->expression()));
auto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(memberAccess->expression()));
solAssert(symbArray, "");
makeArrayPopVerificationTarget(_funCall);
@ -1742,7 +1742,7 @@ void SMTEncoder::arrayPop(FunctionCall const& _funCall)
assignment(memberAccess->expression(), symbArray->currentValue());
}
void SMTEncoder::defineGlobalVariable(string const& _name, Expression const& _expr, bool _increaseIndex)
void SMTEncoder::defineGlobalVariable(std::string const& _name, Expression const& _expr, bool _increaseIndex)
{
if (!m_context.knownGlobalSymbol(_name))
{
@ -1807,7 +1807,7 @@ void SMTEncoder::arithmeticOperation(BinaryOperation const& _op)
}
}
pair<smtutil::Expression, smtutil::Expression> SMTEncoder::arithmeticOperation(
std::pair<smtutil::Expression, smtutil::Expression> SMTEncoder::arithmeticOperation(
Token _op,
smtutil::Expression const& _left,
smtutil::Expression const& _right,
@ -1815,7 +1815,7 @@ pair<smtutil::Expression, smtutil::Expression> SMTEncoder::arithmeticOperation(
Expression const& _operation
)
{
static set<Token> validOperators{
static std::set<Token> validOperators{
Token::Add,
Token::Sub,
Token::Mul,
@ -1862,7 +1862,7 @@ pair<smtutil::Expression, smtutil::Expression> SMTEncoder::arithmeticOperation(
// - RHS is -1
// the result is then -(type.min), which wraps back to type.min
smtutil::Expression maxLeft = _left == smt::minValue(*intType);
smtutil::Expression minusOneRight = _right == numeric_limits<size_t >::max();
smtutil::Expression minusOneRight = _right == std::numeric_limits<size_t >::max();
smtutil::Expression wrap = smtutil::Expression::ite(maxLeft && minusOneRight, smt::minValue(*intType), valueUnbounded);
return {wrap, valueUnbounded};
}
@ -1871,7 +1871,7 @@ pair<smtutil::Expression, smtutil::Expression> SMTEncoder::arithmeticOperation(
auto symbMax = smt::maxValue(*intType);
smtutil::Expression intValueRange = (0 - symbMin) + symbMax + 1;
string suffix = to_string(_operation.id()) + "_" + to_string(m_context.newUniqueId());
std::string suffix = std::to_string(_operation.id()) + "_" + std::to_string(m_context.newUniqueId());
smt::SymbolicIntVariable k(intType, intType, "k_" + suffix, m_context);
smt::SymbolicIntVariable m(intType, intType, "m_" + suffix, m_context);
@ -1905,7 +1905,7 @@ smtutil::Expression SMTEncoder::bitwiseOperation(
Type const* _commonType
)
{
static set<Token> validOperators{
static std::set<Token> validOperators{
Token::BitAnd,
Token::BitOr,
Token::BitXor,
@ -1921,7 +1921,7 @@ smtutil::Expression SMTEncoder::bitwiseOperation(
auto bvLeft = smtutil::Expression::int2bv(_left, bvSize);
auto bvRight = smtutil::Expression::int2bv(_right, bvSize);
optional<smtutil::Expression> result;
std::optional<smtutil::Expression> result;
switch (_op)
{
case Token::BitAnd:
@ -1962,10 +1962,10 @@ void SMTEncoder::compareOperation(BinaryOperation const& _op)
smtutil::Expression left(expr(_op.leftExpression(), commonType));
smtutil::Expression right(expr(_op.rightExpression(), commonType));
Token op = _op.getOperator();
shared_ptr<smtutil::Expression> value;
std::shared_ptr<smtutil::Expression> value;
if (smt::isNumber(*commonType))
{
value = make_shared<smtutil::Expression>(
value = std::make_shared<smtutil::Expression>(
op == Token::Equal ? (left == right) :
op == Token::NotEqual ? (left != right) :
op == Token::LessThan ? (left < right) :
@ -1977,7 +1977,7 @@ void SMTEncoder::compareOperation(BinaryOperation const& _op)
else // Bool
{
solUnimplementedAssert(smt::isBool(*commonType), "Operation not yet supported");
value = make_shared<smtutil::Expression>(
value = std::make_shared<smtutil::Expression>(
op == Token::Equal ? (left == right) :
/*op == Token::NotEqual*/ (left != right)
);
@ -2039,7 +2039,7 @@ void SMTEncoder::bitwiseNotOperation(UnaryOperation const& _op)
defineExpr(_op, smtutil::Expression::bv2int(~bvOperand, isSigned));
}
pair<smtutil::Expression, smtutil::Expression> SMTEncoder::divModWithSlacks(
std::pair<smtutil::Expression, smtutil::Expression> SMTEncoder::divModWithSlacks(
smtutil::Expression _left,
smtutil::Expression _right,
IntegerType const& _type
@ -2049,7 +2049,7 @@ pair<smtutil::Expression, smtutil::Expression> SMTEncoder::divModWithSlacks(
return {_left / _right, _left % _right};
IntegerType const* intType = &_type;
string suffix = "div_mod_" + to_string(m_context.newUniqueId());
std::string suffix = "div_mod_" + std::to_string(m_context.newUniqueId());
smt::SymbolicIntVariable dSymb(intType, intType, "d_" + suffix, m_context);
smt::SymbolicIntVariable rSymb(intType, intType, "r_" + suffix, m_context);
auto d = dSymb.currentValue();
@ -2115,7 +2115,7 @@ void SMTEncoder::assignment(
{
auto memberAccess = dynamic_cast<MemberAccess const*>(&funCall->expression());
solAssert(memberAccess, "");
auto symbArray = dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(memberAccess->expression()));
auto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(memberAccess->expression()));
solAssert(symbArray, "");
auto oldLength = symbArray->length();
@ -2190,14 +2190,14 @@ void SMTEncoder::tupleAssignment(Expression const& _left, Expression const& _rig
smtutil::Expression SMTEncoder::compoundAssignment(Assignment const& _assignment)
{
static map<Token, Token> const compoundToArithmetic{
static std::map<Token, Token> const compoundToArithmetic{
{Token::AssignAdd, Token::Add},
{Token::AssignSub, Token::Sub},
{Token::AssignMul, Token::Mul},
{Token::AssignDiv, Token::Div},
{Token::AssignMod, Token::Mod}
};
static map<Token, Token> const compoundToBitwise{
static std::map<Token, Token> const compoundToBitwise{
{Token::AssignBitAnd, Token::BitAnd},
{Token::AssignBitOr, Token::BitOr},
{Token::AssignBitXor, Token::BitXor},
@ -2228,12 +2228,12 @@ smtutil::Expression SMTEncoder::compoundAssignment(Assignment const& _assignment
return values.first;
}
void SMTEncoder::expressionToTupleAssignment(vector<shared_ptr<VariableDeclaration>> const& _variables, Expression const& _rhs)
void SMTEncoder::expressionToTupleAssignment(std::vector<std::shared_ptr<VariableDeclaration>> const& _variables, Expression const& _rhs)
{
auto symbolicVar = m_context.expression(_rhs);
if (_variables.size() > 1)
{
auto symbTuple = dynamic_pointer_cast<smt::SymbolicTupleVariable>(symbolicVar);
auto symbTuple = std::dynamic_pointer_cast<smt::SymbolicTupleVariable>(symbolicVar);
solAssert(symbTuple, "");
auto const& symbComponents = symbTuple->components();
solAssert(symbComponents.size() == _variables.size(), "");
@ -2282,7 +2282,7 @@ void SMTEncoder::assignment(smt::SymbolicVariable& _symVar, smtutil::Expression
m_context.addAssertion(_symVar.increaseIndex() == _value);
}
pair<SMTEncoder::VariableIndices, smtutil::Expression> SMTEncoder::visitBranch(
std::pair<SMTEncoder::VariableIndices, smtutil::Expression> SMTEncoder::visitBranch(
ASTNode const* _statement,
smtutil::Expression _condition
)
@ -2290,7 +2290,7 @@ pair<SMTEncoder::VariableIndices, smtutil::Expression> SMTEncoder::visitBranch(
return visitBranch(_statement, &_condition);
}
pair<SMTEncoder::VariableIndices, smtutil::Expression> SMTEncoder::visitBranch(
std::pair<SMTEncoder::VariableIndices, smtutil::Expression> SMTEncoder::visitBranch(
ASTNode const* _statement,
smtutil::Expression const* _condition
)
@ -2307,7 +2307,7 @@ pair<SMTEncoder::VariableIndices, smtutil::Expression> SMTEncoder::visitBranch(
return {indicesAfterBranch, pathConditionOnExit};
}
void SMTEncoder::initializeFunctionCallParameters(CallableDeclaration const& _function, vector<smtutil::Expression> const& _callArgs)
void SMTEncoder::initializeFunctionCallParameters(CallableDeclaration const& _function, std::vector<smtutil::Expression> const& _callArgs)
{
auto const& funParams = _function.parameters();
solAssert(funParams.size() == _callArgs.size(), "");
@ -2319,7 +2319,7 @@ void SMTEncoder::initializeFunctionCallParameters(CallableDeclaration const& _fu
m_arrayAssignmentHappened = true;
}
vector<VariableDeclaration const*> localVars;
std::vector<VariableDeclaration const*> localVars;
if (auto const* fun = dynamic_cast<FunctionDefinition const*>(&_function))
localVars = localVariablesIncludingModifiers(*fun, m_currentContract);
else
@ -2560,14 +2560,14 @@ void SMTEncoder::defineExpr(Expression const& _e, smtutil::Expression _value)
));
}
void SMTEncoder::defineExpr(Expression const& _e, vector<optional<smtutil::Expression>> const& _values)
void SMTEncoder::defineExpr(Expression const& _e, std::vector<std::optional<smtutil::Expression>> const& _values)
{
if (_values.size() == 1 && _values.front())
{
defineExpr(_e, *_values.front());
return;
}
auto const& symbTuple = dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(_e));
auto const& symbTuple = std::dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_context.expression(_e));
solAssert(symbTuple, "");
symbTuple->increaseIndex();
auto const& symbComponents = symbTuple->components();
@ -2606,7 +2606,7 @@ smtutil::Expression SMTEncoder::currentPathConditions()
return m_pathConditions.back();
}
SecondarySourceLocation SMTEncoder::callStackMessage(vector<CallStackEntry> const& _callStack)
SecondarySourceLocation SMTEncoder::callStackMessage(std::vector<CallStackEntry> const& _callStack)
{
SecondarySourceLocation callStackLocation;
solAssert(!_callStack.empty(), "");
@ -2617,7 +2617,7 @@ SecondarySourceLocation SMTEncoder::callStackMessage(vector<CallStackEntry> cons
return callStackLocation;
}
pair<CallableDeclaration const*, ASTNode const*> SMTEncoder::popCallStack()
std::pair<CallableDeclaration const*, ASTNode const*> SMTEncoder::popCallStack()
{
solAssert(!m_callStack.empty(), "");
auto lastCalled = m_callStack.back();
@ -2738,7 +2738,7 @@ TypePointers SMTEncoder::replaceUserTypes(TypePointers const& _types)
});
}
pair<Expression const*, FunctionCallOptions const*> SMTEncoder::functionCallExpression(FunctionCall const& _funCall)
std::pair<Expression const*, FunctionCallOptions const*> SMTEncoder::functionCallExpression(FunctionCall const& _funCall)
{
Expression const* callExpr = &_funCall.expression();
auto const* callOptions = dynamic_cast<FunctionCallOptions const*>(callExpr);
@ -2775,9 +2775,9 @@ Expression const* SMTEncoder::cleanExpression(Expression const& _expr)
return expr;
}
set<VariableDeclaration const*> SMTEncoder::touchedVariables(ASTNode const& _node)
std::set<VariableDeclaration const*> SMTEncoder::touchedVariables(ASTNode const& _node)
{
vector<CallableDeclaration const*> callStack;
std::vector<CallableDeclaration const*> callStack;
for (auto const& call: m_callStack)
callStack.push_back(call.first);
return m_variableUsage.touchedVariables(_node, callStack);
@ -2861,9 +2861,9 @@ bool SMTEncoder::isExternalCallToThis(Expression const* _expr) {
;
}
string SMTEncoder::extraComment()
std::string SMTEncoder::extraComment()
{
string extra;
std::string extra;
if (m_arrayAssignmentHappened)
extra +=
"\nNote that array aliasing is not supported,"
@ -2921,28 +2921,28 @@ FunctionDefinition const* SMTEncoder::functionCallToDefinition(
return {};
}
vector<VariableDeclaration const*> SMTEncoder::stateVariablesIncludingInheritedAndPrivate(ContractDefinition const& _contract)
std::vector<VariableDeclaration const*> SMTEncoder::stateVariablesIncludingInheritedAndPrivate(ContractDefinition const& _contract)
{
return fold(
_contract.annotation().linearizedBaseContracts,
vector<VariableDeclaration const*>{},
std::vector<VariableDeclaration const*>{},
[](auto&& _acc, auto _contract) { return _acc + _contract->stateVariables(); }
);
}
vector<VariableDeclaration const*> SMTEncoder::stateVariablesIncludingInheritedAndPrivate(FunctionDefinition const& _function)
std::vector<VariableDeclaration const*> SMTEncoder::stateVariablesIncludingInheritedAndPrivate(FunctionDefinition const& _function)
{
if (auto contract = dynamic_cast<ContractDefinition const*>(_function.scope()))
return stateVariablesIncludingInheritedAndPrivate(*contract);
return {};
}
vector<VariableDeclaration const*> SMTEncoder::localVariablesIncludingModifiers(FunctionDefinition const& _function, ContractDefinition const* _contract)
std::vector<VariableDeclaration const*> SMTEncoder::localVariablesIncludingModifiers(FunctionDefinition const& _function, ContractDefinition const* _contract)
{
return _function.localVariables() + tryCatchVariables(_function) + modifiersVariables(_function, _contract);
}
vector<VariableDeclaration const*> SMTEncoder::tryCatchVariables(FunctionDefinition const& _function)
std::vector<VariableDeclaration const*> SMTEncoder::tryCatchVariables(FunctionDefinition const& _function)
{
struct TryCatchVarsVisitor : public ASTConstVisitor
{
@ -2958,23 +2958,23 @@ vector<VariableDeclaration const*> SMTEncoder::tryCatchVariables(FunctionDefinit
return true;
}
vector<VariableDeclaration const*> vars;
std::vector<VariableDeclaration const*> vars;
} tryCatchVarsVisitor;
_function.accept(tryCatchVarsVisitor);
return tryCatchVarsVisitor.vars;
}
vector<VariableDeclaration const*> SMTEncoder::modifiersVariables(FunctionDefinition const& _function, ContractDefinition const* _contract)
std::vector<VariableDeclaration const*> SMTEncoder::modifiersVariables(FunctionDefinition const& _function, ContractDefinition const* _contract)
{
struct BlockVars: ASTConstVisitor
{
BlockVars(Block const& _block) { _block.accept(*this); }
void endVisit(VariableDeclaration const& _var) { vars.push_back(&_var); }
vector<VariableDeclaration const*> vars;
std::vector<VariableDeclaration const*> vars;
};
vector<VariableDeclaration const*> vars;
set<ModifierDefinition const*> visited;
std::vector<VariableDeclaration const*> vars;
std::set<ModifierDefinition const*> visited;
for (auto invok: _function.modifiers())
{
if (!invok)
@ -3007,12 +3007,12 @@ ModifierDefinition const* SMTEncoder::resolveModifierInvocation(ModifierInvocati
return modifier;
}
set<FunctionDefinition const*, ASTNode::CompareByID> const& SMTEncoder::contractFunctions(ContractDefinition const& _contract)
std::set<FunctionDefinition const*, ASTNode::CompareByID> const& SMTEncoder::contractFunctions(ContractDefinition const& _contract)
{
if (!m_contractFunctions.count(&_contract))
{
auto const& functions = _contract.definedFunctions();
set<FunctionDefinition const*, ASTNode::CompareByID> resolvedFunctions(begin(functions), end(functions));
std::set<FunctionDefinition const*, ASTNode::CompareByID> resolvedFunctions(begin(functions), end(functions));
for (auto const* base: _contract.annotation().linearizedBaseContracts)
{
if (base == &_contract)
@ -3042,7 +3042,7 @@ set<FunctionDefinition const*, ASTNode::CompareByID> const& SMTEncoder::contract
return m_contractFunctions.at(&_contract);
}
set<FunctionDefinition const*, ASTNode::CompareByID> const& SMTEncoder::contractFunctionsWithoutVirtual(ContractDefinition const& _contract)
std::set<FunctionDefinition const*, ASTNode::CompareByID> const& SMTEncoder::contractFunctionsWithoutVirtual(ContractDefinition const& _contract)
{
if (!m_contractFunctionsWithoutVirtual.count(&_contract))
{
@ -3057,9 +3057,9 @@ set<FunctionDefinition const*, ASTNode::CompareByID> const& SMTEncoder::contract
return m_contractFunctionsWithoutVirtual.at(&_contract);
}
map<ContractDefinition const*, vector<ASTPointer<frontend::Expression>>> SMTEncoder::baseArguments(ContractDefinition const& _contract)
std::map<ContractDefinition const*, std::vector<ASTPointer<frontend::Expression>>> SMTEncoder::baseArguments(ContractDefinition const& _contract)
{
map<ContractDefinition const*, vector<ASTPointer<Expression>>> baseArgs;
std::map<ContractDefinition const*, std::vector<ASTPointer<Expression>>> baseArgs;
for (auto contract: _contract.annotation().linearizedBaseContracts)
{
@ -3104,7 +3104,7 @@ RationalNumberType const* SMTEncoder::isConstant(Expression const& _expr)
return nullptr;
}
set<FunctionCall const*, ASTCompareByID<FunctionCall>> SMTEncoder::collectABICalls(ASTNode const* _node)
std::set<FunctionCall const*, ASTCompareByID<FunctionCall>> SMTEncoder::collectABICalls(ASTNode const* _node)
{
struct ABIFunctions: public ASTConstVisitor
{
@ -3126,15 +3126,15 @@ set<FunctionCall const*, ASTCompareByID<FunctionCall>> SMTEncoder::collectABICal
}
}
set<FunctionCall const*, ASTCompareByID<FunctionCall>> abiCalls;
std::set<FunctionCall const*, ASTCompareByID<FunctionCall>> abiCalls;
};
return ABIFunctions(_node).abiCalls;
}
set<SourceUnit const*, ASTNode::CompareByID> SMTEncoder::sourceDependencies(SourceUnit const& _source)
std::set<SourceUnit const*, ASTNode::CompareByID> SMTEncoder::sourceDependencies(SourceUnit const& _source)
{
set<SourceUnit const*, ASTNode::CompareByID> sources;
std::set<SourceUnit const*, ASTNode::CompareByID> sources;
sources.insert(&_source);
for (auto const& source: _source.referencedSourceUnits(true))
sources.insert(source);
@ -3150,24 +3150,24 @@ void SMTEncoder::createReturnedExpressions(FunctionCall const& _funCall, Contrac
auto const& returnParams = funDef->returnParameters();
for (auto param: returnParams)
createVariable(*param);
auto returnValues = applyMap(returnParams, [this](auto const& param) -> optional<smtutil::Expression> {
auto returnValues = applyMap(returnParams, [this](auto const& param) -> std::optional<smtutil::Expression> {
solAssert(param && m_context.knownVariable(*param), "");
return currentValue(*param);
});
defineExpr(_funCall, returnValues);
}
vector<smtutil::Expression> SMTEncoder::symbolicArguments(FunctionCall const& _funCall, ContractDefinition const* _contextContract)
std::vector<smtutil::Expression> SMTEncoder::symbolicArguments(FunctionCall const& _funCall, ContractDefinition const* _contextContract)
{
auto funDef = functionCallToDefinition(_funCall, currentScopeContract(), _contextContract);
solAssert(funDef, "");
vector<smtutil::Expression> args;
std::vector<smtutil::Expression> args;
Expression const* calledExpr = &_funCall.expression();
auto funType = dynamic_cast<FunctionType const*>(calledExpr->annotation().type);
solAssert(funType, "");
vector<ASTPointer<Expression const>> arguments = _funCall.sortedArguments();
std::vector<ASTPointer<Expression const>> arguments = _funCall.sortedArguments();
auto functionParams = funDef->parameters();
unsigned firstParam = 0;
if (funType->hasBoundFirstArgument())
@ -3204,7 +3204,7 @@ smtutil::Expression SMTEncoder::constantExpr(Expression const& _expr, VariableDe
solAssert(false, "");
}
void SMTEncoder::collectFreeFunctions(set<SourceUnit const*, ASTNode::CompareByID> const& _sources)
void SMTEncoder::collectFreeFunctions(std::set<SourceUnit const*, ASTNode::CompareByID> const& _sources)
{
for (auto source: _sources)
for (auto node: source->nodes())
@ -3220,7 +3220,7 @@ void SMTEncoder::collectFreeFunctions(set<SourceUnit const*, ASTNode::CompareByI
m_freeFunctions.insert(function);
}
void SMTEncoder::createFreeConstants(set<SourceUnit const*, ASTNode::CompareByID> const& _sources)
void SMTEncoder::createFreeConstants(std::set<SourceUnit const*, ASTNode::CompareByID> const& _sources)
{
for (auto source: _sources)
for (auto node: source->nodes())

View File

@ -18,7 +18,6 @@
#include <libsolidity/formal/SSAVariable.h>
using namespace std;
using namespace solidity::frontend;
using namespace solidity::frontend::smt;

View File

@ -26,42 +26,41 @@
#include <range/v3/view.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::smtutil;
using namespace solidity::frontend::smt;
BlockchainVariable::BlockchainVariable(
string _name,
map<string, smtutil::SortPointer> _members,
std::string _name,
std::map<std::string, smtutil::SortPointer> _members,
EncodingContext& _context
):
m_name(std::move(_name)),
m_members(std::move(_members)),
m_context(_context)
{
vector<string> members;
vector<SortPointer> sorts;
std::vector<std::string> members;
std::vector<SortPointer> sorts;
for (auto const& [component, sort]: m_members)
{
members.emplace_back(component);
sorts.emplace_back(sort);
m_componentIndices[component] = static_cast<unsigned>(members.size() - 1);
}
m_tuple = make_unique<SymbolicTupleVariable>(
make_shared<smtutil::TupleSort>(m_name + "_type", members, sorts),
m_tuple = std::make_unique<SymbolicTupleVariable>(
std::make_shared<smtutil::TupleSort>(m_name + "_type", members, sorts),
m_name,
m_context
);
}
smtutil::Expression BlockchainVariable::member(string const& _member) const
smtutil::Expression BlockchainVariable::member(std::string const& _member) const
{
return m_tuple->component(m_componentIndices.at(_member));
}
smtutil::Expression BlockchainVariable::assignMember(string const& _member, smtutil::Expression const& _value)
smtutil::Expression BlockchainVariable::assignMember(std::string const& _member, smtutil::Expression const& _value)
{
smtutil::Expression newTuple = smt::assignMember(m_tuple->currentValue(), {{_member, _value}});
m_context.addAssertion(m_tuple->increaseIndex() == newTuple);
@ -104,9 +103,9 @@ smtutil::Expression SymbolicState::blockhash(smtutil::Expression _blockNumber) c
void SymbolicState::newBalances()
{
auto tupleSort = dynamic_pointer_cast<TupleSort>(stateSort());
auto tupleSort = std::dynamic_pointer_cast<TupleSort>(stateSort());
auto balanceSort = tupleSort->components.at(tupleSort->memberToIndex.at("balances"));
SymbolicVariable newBalances(balanceSort, "fresh_balances_" + to_string(m_context.newUniqueId()), m_context);
SymbolicVariable newBalances(balanceSort, "fresh_balances_" + std::to_string(m_context.newUniqueId()), m_context);
m_state->assignMember("balances", newBalances.currentValue());
}
@ -158,7 +157,7 @@ void SymbolicState::newStorage()
{
auto newStorageVar = SymbolicTupleVariable(
m_state->member("storage").sort,
"havoc_storage_" + to_string(m_context.newUniqueId()),
"havoc_storage_" + std::to_string(m_context.newUniqueId()),
m_context
);
m_state->assignMember("storage", newStorageVar.currentValue());
@ -170,7 +169,7 @@ void SymbolicState::writeStateVars(ContractDefinition const& _contract, smtutil:
if (stateVars.empty())
return;
map<string, smtutil::Expression> values;
std::map<std::string, smtutil::Expression> values;
for (auto var: stateVars)
values.emplace(stateVarStorageKey(*var, _contract), m_context.variable(*var)->currentValue());
@ -207,7 +206,7 @@ void SymbolicState::addBalance(smtutil::Expression _address, smtutil::Expression
m_state->assignMember("balances", newBalances);
}
smtutil::Expression SymbolicState::txMember(string const& _member) const
smtutil::Expression SymbolicState::txMember(std::string const& _member) const
{
return m_tx.member(_member);
}
@ -268,8 +267,8 @@ void SymbolicState::prepareForSourceUnit(SourceUnit const& _source, bool _storag
{
auto allSources = _source.referencedSourceUnits(true);
allSources.insert(&_source);
set<FunctionCall const*, ASTCompareByID<FunctionCall>> abiCalls;
set<ContractDefinition const*, ASTCompareByID<ContractDefinition>> contracts;
std::set<FunctionCall const*, ASTCompareByID<FunctionCall>> abiCalls;
std::set<ContractDefinition const*, ASTCompareByID<ContractDefinition>> contracts;
for (auto const& source: allSources)
{
abiCalls += SMTEncoder::collectABICalls(source);
@ -283,34 +282,34 @@ void SymbolicState::prepareForSourceUnit(SourceUnit const& _source, bool _storag
/// Private helpers.
string SymbolicState::contractSuffix(ContractDefinition const& _contract) const
std::string SymbolicState::contractSuffix(ContractDefinition const& _contract) const
{
return "_" + _contract.name() + "_" + to_string(_contract.id());
return "_" + _contract.name() + "_" + std::to_string(_contract.id());
}
string SymbolicState::contractStorageKey(ContractDefinition const& _contract) const
std::string SymbolicState::contractStorageKey(ContractDefinition const& _contract) const
{
return "storage" + contractSuffix(_contract);
}
string SymbolicState::stateVarStorageKey(VariableDeclaration const& _var, ContractDefinition const& _contract) const
std::string SymbolicState::stateVarStorageKey(VariableDeclaration const& _var, ContractDefinition const& _contract) const
{
return _var.name() + "_" + to_string(_var.id()) + contractSuffix(_contract);
return _var.name() + "_" + std::to_string(_var.id()) + contractSuffix(_contract);
}
void SymbolicState::buildState(set<ContractDefinition const*, ASTCompareByID<ContractDefinition>> const& _contracts, bool _allStorages)
void SymbolicState::buildState(std::set<ContractDefinition const*, ASTCompareByID<ContractDefinition>> const& _contracts, bool _allStorages)
{
map<string, SortPointer> stateMembers{
{"balances", make_shared<smtutil::ArraySort>(smtutil::SortProvider::uintSort, smtutil::SortProvider::uintSort)}
std::map<std::string, SortPointer> stateMembers{
{"balances", std::make_shared<smtutil::ArraySort>(smtutil::SortProvider::uintSort, smtutil::SortProvider::uintSort)}
};
if (_allStorages)
{
vector<string> memberNames;
vector<SortPointer> memberSorts;
std::vector<std::string> memberNames;
std::vector<SortPointer> memberSorts;
for (auto contract: _contracts)
{
string suffix = contractSuffix(*contract);
std::string suffix = contractSuffix(*contract);
// z3 doesn't like empty tuples, so if the contract has 0
// state vars we can't put it there.
@ -319,16 +318,16 @@ void SymbolicState::buildState(set<ContractDefinition const*, ASTCompareByID<Con
continue;
auto names = applyMap(stateVars, [&](auto var) {
return var->name() + "_" + to_string(var->id()) + suffix;
return var->name() + "_" + std::to_string(var->id()) + suffix;
});
auto sorts = applyMap(stateVars, [](auto var) { return smtSortAbstractFunction(*var->type()); });
string name = "storage" + suffix;
auto storageTuple = make_shared<smtutil::TupleSort>(
std::string name = "storage" + suffix;
auto storageTuple = std::make_shared<smtutil::TupleSort>(
name + "_type", names, sorts
);
auto storageSort = make_shared<smtutil::ArraySort>(
auto storageSort = std::make_shared<smtutil::ArraySort>(
smtSort(*TypeProvider::address()),
storageTuple
);
@ -339,26 +338,26 @@ void SymbolicState::buildState(set<ContractDefinition const*, ASTCompareByID<Con
stateMembers.emplace(
"isActive",
make_shared<smtutil::ArraySort>(smtSort(*TypeProvider::address()), smtutil::SortProvider::boolSort)
std::make_shared<smtutil::ArraySort>(smtSort(*TypeProvider::address()), smtutil::SortProvider::boolSort)
);
stateMembers.emplace(
"storage",
make_shared<smtutil::TupleSort>(
std::make_shared<smtutil::TupleSort>(
"storage_type", memberNames, memberSorts
)
);
}
m_state = make_unique<BlockchainVariable>(
m_state = std::make_unique<BlockchainVariable>(
"state",
std::move(stateMembers),
m_context
);
}
void SymbolicState::buildABIFunctions(set<FunctionCall const*, ASTCompareByID<FunctionCall>> const& _abiFunctions)
void SymbolicState::buildABIFunctions(std::set<FunctionCall const*, ASTCompareByID<FunctionCall>> const& _abiFunctions)
{
map<string, SortPointer> functions;
std::map<std::string, SortPointer> functions;
for (auto const* funCall: _abiFunctions)
{
@ -375,8 +374,8 @@ void SymbolicState::buildABIFunctions(set<FunctionCall const*, ASTCompareByID<Fu
/// Since each abi.* function may have a different number of input/output parameters,
/// we generically compute those types.
vector<frontend::Type const*> inTypes;
vector<frontend::Type const*> outTypes;
std::vector<frontend::Type const*> inTypes;
std::vector<frontend::Type const*> outTypes;
if (t->kind() == FunctionType::Kind::ABIDecode)
{
/// abi.decode : (bytes, tuple_of_types(return_types)) -> (return_types)
@ -415,7 +414,7 @@ void SymbolicState::buildABIFunctions(set<FunctionCall const*, ASTCompareByID<Fu
/// abi.encodeWithSelector : (bytes4, one_or_more_types) -> bytes
/// abi.encodeWithSignature : (string, one_or_more_types) -> bytes
inTypes.emplace_back(paramTypes.front());
inTypes += argTypes(vector<ASTPointer<Expression const>>(args.begin() + 1, args.end()));
inTypes += argTypes(std::vector<ASTPointer<Expression const>>(args.begin() + 1, args.end()));
}
else
{
@ -455,25 +454,25 @@ void SymbolicState::buildABIFunctions(set<FunctionCall const*, ASTCompareByID<Fu
/// If there is only one input or output parameter, we use that type directly.
/// Otherwise we create a tuple wrapping the necessary input or output types.
auto typesToSort = [](auto const& _types, string const& _name) -> shared_ptr<Sort> {
auto typesToSort = [](auto const& _types, std::string const& _name) -> std::shared_ptr<Sort> {
if (_types.size() == 1)
return smtSortAbstractFunction(*_types.front());
vector<string> inNames;
vector<SortPointer> sorts;
std::vector<std::string> inNames;
std::vector<SortPointer> sorts;
for (unsigned i = 0; i < _types.size(); ++i)
{
inNames.emplace_back(_name + "_input_" + to_string(i));
inNames.emplace_back(_name + "_input_" + std::to_string(i));
sorts.emplace_back(smtSortAbstractFunction(*_types.at(i)));
}
return make_shared<smtutil::TupleSort>(
return std::make_shared<smtutil::TupleSort>(
_name + "_input",
inNames,
sorts
);
};
auto functionSort = make_shared<smtutil::ArraySort>(
auto functionSort = std::make_shared<smtutil::ArraySort>(
typesToSort(inTypes, name),
typesToSort(outTypes, name)
);
@ -481,13 +480,13 @@ void SymbolicState::buildABIFunctions(set<FunctionCall const*, ASTCompareByID<Fu
functions[name] = functionSort;
}
m_abi = make_unique<BlockchainVariable>("abi", std::move(functions), m_context);
m_abi = std::make_unique<BlockchainVariable>("abi", std::move(functions), m_context);
}
smtutil::Expression SymbolicState::abiFunction(frontend::FunctionCall const* _funCall)
{
solAssert(m_abi, "");
return m_abi->member(get<0>(m_abiMembers.at(_funCall)));
return m_abi->member(std::get<0>(m_abiMembers.at(_funCall)));
}
SymbolicState::SymbolicABIFunction const& SymbolicState::abiFunctionTypes(FunctionCall const* _funCall) const

View File

@ -26,7 +26,6 @@
#include <memory>
#include <vector>
using namespace std;
using namespace solidity::util;
using namespace solidity::smtutil;
@ -52,7 +51,7 @@ SortPointer smtSort(frontend::Type const& _type)
{
auto fType = dynamic_cast<frontend::FunctionType const*>(&_type);
solAssert(fType, "");
vector<SortPointer> parameterSorts = smtSort(fType->parameterTypes());
std::vector<SortPointer> parameterSorts = smtSort(fType->parameterTypes());
auto returnTypes = fType->returnParameterTypes();
SortPointer returnSort;
// TODO change this when we support tuples.
@ -64,22 +63,22 @@ SortPointer smtSort(frontend::Type const& _type)
returnSort = SortProvider::uintSort;
else
returnSort = smtSort(*returnTypes.front());
return make_shared<FunctionSort>(parameterSorts, returnSort);
return std::make_shared<FunctionSort>(parameterSorts, returnSort);
}
case Kind::Array:
{
shared_ptr<ArraySort> array;
std::shared_ptr<ArraySort> array;
if (isMapping(_type))
{
auto mapType = dynamic_cast<frontend::MappingType const*>(&_type);
solAssert(mapType, "");
array = make_shared<ArraySort>(smtSortAbstractFunction(*mapType->keyType()), smtSortAbstractFunction(*mapType->valueType()));
array = std::make_shared<ArraySort>(smtSortAbstractFunction(*mapType->keyType()), smtSortAbstractFunction(*mapType->valueType()));
}
else if (isStringLiteral(_type))
{
auto stringLitType = dynamic_cast<frontend::StringLiteralType const*>(&_type);
solAssert(stringLitType, "");
array = make_shared<ArraySort>(SortProvider::uintSort, SortProvider::uintSort);
array = std::make_shared<ArraySort>(SortProvider::uintSort, SortProvider::uintSort);
}
else
{
@ -92,10 +91,10 @@ SortPointer smtSort(frontend::Type const& _type)
solAssert(false, "");
solAssert(arrayType, "");
array = make_shared<ArraySort>(SortProvider::uintSort, smtSortAbstractFunction(*arrayType->baseType()));
array = std::make_shared<ArraySort>(SortProvider::uintSort, smtSortAbstractFunction(*arrayType->baseType()));
}
string tupleName;
std::string tupleName;
auto sliceArrayType = dynamic_cast<ArraySliceType const*>(&_type);
ArrayType const* arrayType = sliceArrayType ? &sliceArrayType->arrayType() : dynamic_cast<ArrayType const*>(&_type);
if (
@ -109,7 +108,7 @@ SortPointer smtSort(frontend::Type const& _type)
// Solidity allows implicit conversion also when assigning arrays.
// So if the base type potentially has a size, that size cannot go
// in the tuple's name.
if (auto tupleSort = dynamic_pointer_cast<TupleSort>(array->range))
if (auto tupleSort = std::dynamic_pointer_cast<TupleSort>(array->range))
tupleName = tupleSort->name;
else if (
baseType->category() == frontend::Type::Category::Integer ||
@ -128,23 +127,23 @@ SortPointer smtSort(frontend::Type const& _type)
tupleName += "_tuple";
return make_shared<TupleSort>(
return std::make_shared<TupleSort>(
tupleName,
vector<string>{tupleName + "_accessor_array", tupleName + "_accessor_length"},
vector<SortPointer>{array, SortProvider::uintSort}
std::vector<std::string>{tupleName + "_accessor_array", tupleName + "_accessor_length"},
std::vector<SortPointer>{array, SortProvider::uintSort}
);
}
case Kind::Tuple:
{
vector<string> members;
std::vector<std::string> members;
auto const& tupleName = _type.toString(true);
vector<SortPointer> sorts;
std::vector<SortPointer> sorts;
if (auto const* tupleType = dynamic_cast<frontend::TupleType const*>(&_type))
{
auto const& components = tupleType->components();
for (unsigned i = 0; i < components.size(); ++i)
members.emplace_back(tupleName + "_accessor_" + to_string(i));
members.emplace_back(tupleName + "_accessor_" + std::to_string(i));
sorts = smtSortAbstractFunction(tupleType->components());
}
else if (auto const* structType = dynamic_cast<frontend::StructType const*>(&_type))
@ -161,7 +160,7 @@ SortPointer smtSort(frontend::Type const& _type)
else
solAssert(false, "");
return make_shared<TupleSort>(tupleName, members, sorts);
return std::make_shared<TupleSort>(tupleName, members, sorts);
}
default:
// Abstract case.
@ -169,9 +168,9 @@ SortPointer smtSort(frontend::Type const& _type)
}
}
vector<SortPointer> smtSort(vector<frontend::Type const*> const& _types)
std::vector<SortPointer> smtSort(std::vector<frontend::Type const*> const& _types)
{
vector<SortPointer> sorts;
std::vector<SortPointer> sorts;
for (auto const& type: _types)
sorts.push_back(smtSort(*type));
return sorts;
@ -184,9 +183,9 @@ SortPointer smtSortAbstractFunction(frontend::Type const& _type)
return smtSort(_type);
}
vector<SortPointer> smtSortAbstractFunction(vector<frontend::Type const*> const& _types)
std::vector<SortPointer> smtSortAbstractFunction(std::vector<frontend::Type const*> const& _types)
{
vector<SortPointer> sorts;
std::vector<SortPointer> sorts;
for (auto const& type: _types)
if (type)
sorts.push_back(smtSortAbstractFunction(*type));
@ -233,14 +232,14 @@ bool isSupportedTypeDeclaration(frontend::Type const& _type)
isFunction(_type);
}
pair<bool, shared_ptr<SymbolicVariable>> newSymbolicVariable(
std::pair<bool, std::shared_ptr<SymbolicVariable>> newSymbolicVariable(
frontend::Type const& _type,
std::string const& _uniqueName,
EncodingContext& _context
)
{
bool abstract = false;
shared_ptr<SymbolicVariable> var;
std::shared_ptr<SymbolicVariable> var;
frontend::Type const* type = &_type;
if (auto userType = dynamic_cast<UserDefinedValueType const*>(type))
@ -249,10 +248,10 @@ pair<bool, shared_ptr<SymbolicVariable>> newSymbolicVariable(
if (!isSupportedTypeDeclaration(_type))
{
abstract = true;
var = make_shared<SymbolicIntVariable>(frontend::TypeProvider::uint256(), type, _uniqueName, _context);
var = std::make_shared<SymbolicIntVariable>(frontend::TypeProvider::uint256(), type, _uniqueName, _context);
}
else if (isBool(_type))
var = make_shared<SymbolicBoolVariable>(type, _uniqueName, _context);
var = std::make_shared<SymbolicBoolVariable>(type, _uniqueName, _context);
else if (isFunction(_type))
{
auto const& fType = dynamic_cast<FunctionType const*>(type);
@ -271,45 +270,45 @@ pair<bool, shared_ptr<SymbolicVariable>> newSymbolicVariable(
)
{
abstract = true;
var = make_shared<SymbolicIntVariable>(TypeProvider::uint256(), type, _uniqueName, _context);
var = std::make_shared<SymbolicIntVariable>(TypeProvider::uint256(), type, _uniqueName, _context);
}
else
var = make_shared<SymbolicFunctionVariable>(type, _uniqueName, _context);
var = std::make_shared<SymbolicFunctionVariable>(type, _uniqueName, _context);
}
else if (isInteger(_type))
var = make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);
var = std::make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);
else if (isFixedPoint(_type))
var = make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);
var = std::make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);
else if (isFixedBytes(_type))
{
auto fixedBytesType = dynamic_cast<frontend::FixedBytesType const*>(type);
solAssert(fixedBytesType, "");
var = make_shared<SymbolicFixedBytesVariable>(type, fixedBytesType->numBytes(), _uniqueName, _context);
var = std::make_shared<SymbolicFixedBytesVariable>(type, fixedBytesType->numBytes(), _uniqueName, _context);
}
else if (isAddress(_type) || isContract(_type))
var = make_shared<SymbolicAddressVariable>(_uniqueName, _context);
var = std::make_shared<SymbolicAddressVariable>(_uniqueName, _context);
else if (isEnum(_type))
var = make_shared<SymbolicEnumVariable>(type, _uniqueName, _context);
var = std::make_shared<SymbolicEnumVariable>(type, _uniqueName, _context);
else if (isRational(_type))
{
auto rational = dynamic_cast<frontend::RationalNumberType const*>(&_type);
solAssert(rational, "");
if (rational->isFractional())
var = make_shared<SymbolicIntVariable>(frontend::TypeProvider::uint256(), type, _uniqueName, _context);
var = std::make_shared<SymbolicIntVariable>(frontend::TypeProvider::uint256(), type, _uniqueName, _context);
else
var = make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);
var = std::make_shared<SymbolicIntVariable>(type, type, _uniqueName, _context);
}
else if (isMapping(_type) || isArray(_type))
var = make_shared<SymbolicArrayVariable>(type, type, _uniqueName, _context);
var = std::make_shared<SymbolicArrayVariable>(type, type, _uniqueName, _context);
else if (isTuple(_type))
var = make_shared<SymbolicTupleVariable>(type, _uniqueName, _context);
var = std::make_shared<SymbolicTupleVariable>(type, _uniqueName, _context);
else if (isStringLiteral(_type))
{
auto stringType = TypeProvider::stringMemory();
var = make_shared<SymbolicArrayVariable>(stringType, type, _uniqueName, _context);
var = std::make_shared<SymbolicArrayVariable>(stringType, type, _uniqueName, _context);
}
else if (isNonRecursiveStruct(_type))
var = make_shared<SymbolicStructVariable>(type, _uniqueName, _context);
var = std::make_shared<SymbolicStructVariable>(type, _uniqueName, _context);
else
solAssert(false, "");
return make_pair(abstract, var);
@ -482,9 +481,9 @@ smtutil::Expression zeroValue(frontend::Type const* _type)
return smtutil::Expression(false);
if (isArray(*_type) || isMapping(*_type))
{
auto tupleSort = dynamic_pointer_cast<TupleSort>(smtSort(*_type));
auto tupleSort = std::dynamic_pointer_cast<TupleSort>(smtSort(*_type));
solAssert(tupleSort, "");
auto sortSort = make_shared<SortSort>(tupleSort->components.front());
auto sortSort = std::make_shared<SortSort>(tupleSort->components.front());
std::optional<smtutil::Expression> zeroArray;
auto length = bigint(0);
@ -502,16 +501,16 @@ smtutil::Expression zeroValue(frontend::Type const* _type)
solAssert(zeroArray, "");
return smtutil::Expression::tuple_constructor(
smtutil::Expression(std::make_shared<SortSort>(tupleSort), tupleSort->name),
vector<smtutil::Expression>{*zeroArray, length}
std::vector<smtutil::Expression>{*zeroArray, length}
);
}
if (isNonRecursiveStruct(*_type))
{
auto const* structType = dynamic_cast<StructType const*>(_type);
auto structSort = dynamic_pointer_cast<TupleSort>(smtSort(*_type));
auto structSort = std::dynamic_pointer_cast<TupleSort>(smtSort(*_type));
return smtutil::Expression::tuple_constructor(
smtutil::Expression(make_shared<SortSort>(structSort), structSort->name),
smtutil::Expression(std::make_shared<SortSort>(structSort), structSort->name),
applyMap(
structType->structDefinition().members(),
[](auto var) { return zeroValue(var->type()); }
@ -550,7 +549,7 @@ bool isSigned(frontend::Type const* _type)
return isSigned;
}
pair<unsigned, bool> typeBvSizeAndSignedness(frontend::Type const* _type)
std::pair<unsigned, bool> typeBvSizeAndSignedness(frontend::Type const* _type)
{
if (auto userType = dynamic_cast<UserDefinedValueType const*>(_type))
return typeBvSizeAndSignedness(&userType->underlyingType());
@ -596,7 +595,7 @@ smtutil::Expression symbolicUnknownConstraints(smtutil::Expression _expr, fronte
return smtutil::Expression(true);
}
optional<smtutil::Expression> symbolicTypeConversion(frontend::Type const* _from, frontend::Type const* _to)
std::optional<smtutil::Expression> symbolicTypeConversion(frontend::Type const* _from, frontend::Type const* _to)
{
if (auto userType = dynamic_cast<UserDefinedValueType const*>(_to))
return symbolicTypeConversion(_from, &userType->underlyingType());
@ -618,7 +617,7 @@ optional<smtutil::Expression> symbolicTypeConversion(frontend::Type const* _from
return std::nullopt;
}
smtutil::Expression member(smtutil::Expression const& _tuple, string const& _member)
smtutil::Expression member(smtutil::Expression const& _tuple, std::string const& _member)
{
TupleSort const& _sort = dynamic_cast<TupleSort const&>(*_tuple.sort);
return smtutil::Expression::tuple_get(
@ -627,16 +626,16 @@ smtutil::Expression member(smtutil::Expression const& _tuple, string const& _mem
);
}
smtutil::Expression assignMember(smtutil::Expression const _tuple, map<string, smtutil::Expression> const& _values)
smtutil::Expression assignMember(smtutil::Expression const _tuple, std::map<std::string, smtutil::Expression> const& _values)
{
TupleSort const& _sort = dynamic_cast<TupleSort const&>(*_tuple.sort);
vector<smtutil::Expression> args;
std::vector<smtutil::Expression> args;
for (auto const& m: _sort.members)
if (auto* value = util::valueOrNullptr(_values, m))
args.emplace_back(*value);
else
args.emplace_back(member(_tuple, m));
auto sortExpr = smtutil::Expression(make_shared<smtutil::SortSort>(_tuple.sort), _tuple.name);
auto sortExpr = smtutil::Expression(std::make_shared<smtutil::SortSort>(_tuple.sort), _tuple.name);
return smtutil::Expression::tuple_constructor(sortExpr, args);
}

View File

@ -23,7 +23,6 @@
#include <libsolutil/Algorithms.h>
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::smtutil;
@ -33,14 +32,14 @@ using namespace solidity::frontend::smt;
SymbolicVariable::SymbolicVariable(
frontend::Type const* _type,
frontend::Type const* _originalType,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
m_type(_type),
m_originalType(_originalType),
m_uniqueName(std::move(_uniqueName)),
m_context(_context),
m_ssa(make_unique<SSAVariable>())
m_ssa(std::make_unique<SSAVariable>())
{
solAssert(m_type, "");
m_sort = smtSort(*m_type);
@ -49,13 +48,13 @@ SymbolicVariable::SymbolicVariable(
SymbolicVariable::SymbolicVariable(
SortPointer _sort,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
m_sort(std::move(_sort)),
m_uniqueName(std::move(_uniqueName)),
m_context(_context),
m_ssa(make_unique<SSAVariable>())
m_ssa(std::make_unique<SSAVariable>())
{
solAssert(m_sort, "");
}
@ -65,7 +64,7 @@ smtutil::Expression SymbolicVariable::currentValue(frontend::Type const*) const
return valueAtIndex(m_ssa->index());
}
string SymbolicVariable::currentName() const
std::string SymbolicVariable::currentName() const
{
return uniqueSymbol(m_ssa->index());
}
@ -75,14 +74,14 @@ smtutil::Expression SymbolicVariable::valueAtIndex(unsigned _index) const
return m_context.newVariable(uniqueSymbol(_index), m_sort);
}
string SymbolicVariable::nameAtIndex(unsigned _index) const
std::string SymbolicVariable::nameAtIndex(unsigned _index) const
{
return uniqueSymbol(_index);
}
string SymbolicVariable::uniqueSymbol(unsigned _index) const
std::string SymbolicVariable::uniqueSymbol(unsigned _index) const
{
return m_uniqueName + "_" + to_string(_index);
return m_uniqueName + "_" + std::to_string(_index);
}
smtutil::Expression SymbolicVariable::resetIndex()
@ -105,7 +104,7 @@ smtutil::Expression SymbolicVariable::increaseIndex()
SymbolicBoolVariable::SymbolicBoolVariable(
frontend::Type const* _type,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
SymbolicVariable(_type, _type, std::move(_uniqueName), _context)
@ -116,7 +115,7 @@ SymbolicBoolVariable::SymbolicBoolVariable(
SymbolicIntVariable::SymbolicIntVariable(
frontend::Type const* _type,
frontend::Type const* _originalType,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
SymbolicVariable(_type, _originalType, std::move(_uniqueName), _context)
@ -125,7 +124,7 @@ SymbolicIntVariable::SymbolicIntVariable(
}
SymbolicAddressVariable::SymbolicAddressVariable(
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
SymbolicIntVariable(TypeProvider::uint(160), TypeProvider::uint(160), std::move(_uniqueName), _context)
@ -135,7 +134,7 @@ SymbolicAddressVariable::SymbolicAddressVariable(
SymbolicFixedBytesVariable::SymbolicFixedBytesVariable(
frontend::Type const* _originalType,
unsigned _numBytes,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
SymbolicIntVariable(TypeProvider::uint(_numBytes * 8), _originalType, std::move(_uniqueName), _context)
@ -144,7 +143,7 @@ SymbolicFixedBytesVariable::SymbolicFixedBytesVariable(
SymbolicFunctionVariable::SymbolicFunctionVariable(
frontend::Type const* _type,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
SymbolicVariable(_type, _type, std::move(_uniqueName), _context),
@ -155,7 +154,7 @@ SymbolicFunctionVariable::SymbolicFunctionVariable(
SymbolicFunctionVariable::SymbolicFunctionVariable(
SortPointer _sort,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
SymbolicVariable(std::move(_sort), std::move(_uniqueName), _context),
@ -204,7 +203,7 @@ smtutil::Expression SymbolicFunctionVariable::increaseIndex()
return m_abstract.currentValue();
}
smtutil::Expression SymbolicFunctionVariable::operator()(vector<smtutil::Expression> _arguments) const
smtutil::Expression SymbolicFunctionVariable::operator()(std::vector<smtutil::Expression> _arguments) const
{
return m_declaration(_arguments);
}
@ -216,7 +215,7 @@ void SymbolicFunctionVariable::resetDeclaration()
SymbolicEnumVariable::SymbolicEnumVariable(
frontend::Type const* _type,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
SymbolicVariable(_type, _type, std::move(_uniqueName), _context)
@ -226,7 +225,7 @@ SymbolicEnumVariable::SymbolicEnumVariable(
SymbolicTupleVariable::SymbolicTupleVariable(
frontend::Type const* _type,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
SymbolicVariable(_type, _type, std::move(_uniqueName), _context)
@ -236,7 +235,7 @@ SymbolicTupleVariable::SymbolicTupleVariable(
SymbolicTupleVariable::SymbolicTupleVariable(
SortPointer _sort,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
SymbolicVariable(std::move(_sort), std::move(_uniqueName), _context)
@ -249,22 +248,22 @@ smtutil::Expression SymbolicTupleVariable::currentValue(frontend::Type const* _t
if (!_targetType || sort() == smtSort(*_targetType))
return SymbolicVariable::currentValue();
auto thisTuple = dynamic_pointer_cast<TupleSort>(sort());
auto otherTuple = dynamic_pointer_cast<TupleSort>(smtSort(*_targetType));
auto thisTuple = std::dynamic_pointer_cast<TupleSort>(sort());
auto otherTuple = std::dynamic_pointer_cast<TupleSort>(smtSort(*_targetType));
solAssert(thisTuple && otherTuple, "");
solAssert(thisTuple->components.size() == otherTuple->components.size(), "");
vector<smtutil::Expression> args;
std::vector<smtutil::Expression> args;
for (size_t i = 0; i < thisTuple->components.size(); ++i)
args.emplace_back(component(i, type(), _targetType));
return smtutil::Expression::tuple_constructor(
smtutil::Expression(make_shared<smtutil::SortSort>(smtSort(*_targetType)), ""),
smtutil::Expression(std::make_shared<smtutil::SortSort>(smtSort(*_targetType)), ""),
args
);
}
vector<SortPointer> const& SymbolicTupleVariable::components() const
std::vector<SortPointer> const& SymbolicTupleVariable::components() const
{
auto tupleSort = dynamic_pointer_cast<TupleSort>(m_sort);
auto tupleSort = std::dynamic_pointer_cast<TupleSort>(m_sort);
solAssert(tupleSort, "");
return tupleSort->components;
}
@ -275,7 +274,7 @@ smtutil::Expression SymbolicTupleVariable::component(
frontend::Type const* _toType
) const
{
optional<smtutil::Expression> conversion = symbolicTypeConversion(_fromType, _toType);
std::optional<smtutil::Expression> conversion = symbolicTypeConversion(_fromType, _toType);
if (conversion)
return *conversion;
@ -285,7 +284,7 @@ smtutil::Expression SymbolicTupleVariable::component(
SymbolicArrayVariable::SymbolicArrayVariable(
frontend::Type const* _type,
frontend::Type const* _originalType,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
SymbolicVariable(_type, _originalType, std::move(_uniqueName), _context),
@ -300,7 +299,7 @@ SymbolicArrayVariable::SymbolicArrayVariable(
SymbolicArrayVariable::SymbolicArrayVariable(
SortPointer _sort,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
SymbolicVariable(std::move(_sort), std::move(_uniqueName), _context),
@ -319,7 +318,7 @@ SymbolicArrayVariable::SymbolicArrayVariable(
smtutil::Expression SymbolicArrayVariable::currentValue(frontend::Type const* _targetType) const
{
optional<smtutil::Expression> conversion = symbolicTypeConversion(m_originalType, _targetType);
std::optional<smtutil::Expression> conversion = symbolicTypeConversion(m_originalType, _targetType);
if (conversion)
return *conversion;
@ -343,7 +342,7 @@ smtutil::Expression SymbolicArrayVariable::length() const
SymbolicStructVariable::SymbolicStructVariable(
frontend::Type const* _type,
string _uniqueName,
std::string _uniqueName,
EncodingContext& _context
):
SymbolicVariable(_type, _type, std::move(_uniqueName), _context)
@ -359,12 +358,12 @@ SymbolicStructVariable::SymbolicStructVariable(
}
}
smtutil::Expression SymbolicStructVariable::member(string const& _member) const
smtutil::Expression SymbolicStructVariable::member(std::string const& _member) const
{
return smtutil::Expression::tuple_get(currentValue(), m_memberIndices.at(_member));
}
smtutil::Expression SymbolicStructVariable::assignMember(string const& _member, smtutil::Expression const& _memberValue)
smtutil::Expression SymbolicStructVariable::assignMember(std::string const& _member, smtutil::Expression const& _memberValue)
{
auto const* structType = dynamic_cast<StructType const*>(m_type);
solAssert(structType, "");
@ -385,7 +384,7 @@ smtutil::Expression SymbolicStructVariable::assignMember(string const& _member,
return currentValue();
}
smtutil::Expression SymbolicStructVariable::assignAllMembers(vector<smtutil::Expression> const& _memberValues)
smtutil::Expression SymbolicStructVariable::assignAllMembers(std::vector<smtutil::Expression> const& _memberValues)
{
auto structType = dynamic_cast<StructType const*>(m_type);
solAssert(structType, "");

View File

@ -25,13 +25,12 @@
#include <algorithm>
using namespace std;
using namespace solidity;
using namespace solidity::util;
using namespace solidity::frontend;
using namespace solidity::frontend::smt;
set<VariableDeclaration const*> VariableUsage::touchedVariables(ASTNode const& _node, vector<CallableDeclaration const*> const& _outerCallstack)
std::set<VariableDeclaration const*> VariableUsage::touchedVariables(ASTNode const& _node, std::vector<CallableDeclaration const*> const& _outerCallstack)
{
m_touchedVariables.clear();
m_callStack.clear();

View File

@ -23,7 +23,6 @@
#include <libsolidity/ast/AST.h>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
@ -42,9 +41,9 @@ bool anyDataStoredInStorage(TypePointers const& _pointers)
Json::Value ABI::generate(ContractDefinition const& _contractDef)
{
auto compare = [](Json::Value const& _a, Json::Value const& _b) -> bool {
return make_tuple(_a["type"], _a["name"]) < make_tuple(_b["type"], _b["name"]);
return std::make_tuple(_a["type"], _a["name"]) < std::make_tuple(_b["type"], _b["name"]);
};
multiset<Json::Value, decltype(compare)> abi(compare);
std::multiset<Json::Value, decltype(compare)> abi(compare);
for (auto it: _contractDef.interfaceFunctions())
{
@ -144,9 +143,9 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef)
}
Json::Value ABI::formatTypeList(
vector<string> const& _names,
vector<Type const*> const& _encodingTypes,
vector<Type const*> const& _solidityTypes,
std::vector<std::string> const& _names,
std::vector<Type const*> const& _encodingTypes,
std::vector<Type const*> const& _solidityTypes,
bool _forLibrary
)
{
@ -162,7 +161,7 @@ Json::Value ABI::formatTypeList(
}
Json::Value ABI::formatType(
string const& _name,
std::string const& _name,
Type const& _encodingType,
Type const& _solidityType,
bool _forLibrary
@ -171,7 +170,7 @@ Json::Value ABI::formatType(
Json::Value ret{Json::objectValue};
ret["name"] = _name;
ret["internalType"] = _solidityType.toString(true);
string suffix = (_forLibrary && _encodingType.dataStoredIn(DataLocation::Storage)) ? " storage" : "";
std::string suffix = (_forLibrary && _encodingType.dataStoredIn(DataLocation::Storage)) ? " storage" : "";
if (_encodingType.isValueType() || (_forLibrary && _encodingType.dataStoredIn(DataLocation::Storage)))
ret["type"] = _encodingType.canonicalName() + suffix;
else if (ArrayType const* arrayType = dynamic_cast<ArrayType const*>(&_encodingType))
@ -180,11 +179,11 @@ Json::Value ABI::formatType(
ret["type"] = _encodingType.canonicalName() + suffix;
else
{
string suffix;
std::string suffix;
if (arrayType->isDynamicallySized())
suffix = "[]";
else
suffix = string("[") + arrayType->length().str() + "]";
suffix = std::string("[") + arrayType->length().str() + "]";
solAssert(arrayType->baseType(), "");
Json::Value subtype = formatType(
"",

File diff suppressed because it is too large Load Diff

View File

@ -81,13 +81,15 @@ class Compiler;
class GlobalContext;
class Natspec;
class DeclarationContainer;
namespace experimental
{
class Analysis;
}
/**
* Easy to use and self-contained Solidity compiler with as few header dependencies as possible.
* It holds state and can be used to either step through the compilation stages (and abort e.g.
* before compilation to bytecode) or run the whole compilation in one call.
* If error recovery is active, it is possible to progress through the stages even when
* there are errors. In any case, producing code is only possible without errors.
*/
class CompilerStack: public langutil::CharStreamProvider
{
@ -101,7 +103,7 @@ public:
SourcesSet,
Parsed,
ParsedAndImported,
AnalysisPerformed,
AnalysisSuccessful,
CompilationSuccessful
};
@ -137,10 +139,6 @@ public:
/// @returns the current state.
State state() const { return m_stackState; }
bool hasError() const { return m_hasError; }
bool compilationSuccessful() const { return m_stackState >= CompilationSuccessful; }
/// Resets the compiler to an empty state. Unless @a _keepSettings is set to true,
/// all settings are reset as well.
void reset(bool _keepSettings = false);
@ -164,14 +162,6 @@ public:
/// Sets whether to strip revert strings, add additional strings or do nothing at all.
void setRevertStringBehaviour(RevertStrings _revertStrings);
/// Set whether or not parser error is desired.
/// When called without an argument it will revert to the default.
/// Must be set before parsing.
void setParserErrorRecovery(bool _wantErrorRecovery = false)
{
m_parserErrorRecovery = _wantErrorRecovery;
}
/// Sets the pipeline to go through the Yul IR or not.
/// Must be set before parsing.
void setViaIR(bool _viaIR);
@ -421,6 +411,14 @@ private:
/// @returns true if the contract is requested to be compiled.
bool isRequestedContract(ContractDefinition const& _contract) const;
/// Perform the analysis steps of legacy language mode.
/// @returns false on error.
bool analyzeLegacy(bool _noErrorsSoFar);
/// Perform the analysis steps of experimental language mode.
/// @returns false on error.
bool analyzeExperimental();
/// Assembles the contract.
/// This function should only be internally called by compileContract and generateEVMFromIR.
void assembleYul(
@ -514,15 +512,12 @@ private:
langutil::ErrorList m_errorList;
langutil::ErrorReporter m_errorReporter;
std::unique_ptr<experimental::Analysis> m_experimentalAnalysis;
bool m_metadataLiteralSources = false;
MetadataHash m_metadataHash = MetadataHash::IPFS;
langutil::DebugInfoSelection m_debugInfoSelection = langutil::DebugInfoSelection::Default();
bool m_parserErrorRecovery = false;
State m_stackState = Empty;
CompilationSourceType m_compilationSourceType = CompilationSourceType::Solidity;
/// Whether or not there has been an error during processing.
/// If this is true, the stack will refuse to generate code.
bool m_hasError = false;
MetadataFormat m_metadataFormat = defaultMetadataFormat();
};

View File

@ -35,17 +35,13 @@ using solidity::langutil::InternalCompilerError;
using solidity::util::errinfo_comment;
using solidity::util::readFileAsString;
using solidity::util::joinHumanReadable;
using std::map;
using std::reference_wrapper;
using std::string;
using std::vector;
namespace solidity::frontend
{
FileReader::FileReader(
boost::filesystem::path _basePath,
vector<boost::filesystem::path> const& _includePaths,
std::vector<boost::filesystem::path> const& _includePaths,
FileSystemPathSet _allowedDirectories
):
m_allowedDirectories(std::move(_allowedDirectories)),
@ -99,19 +95,19 @@ void FileReader::setSourceUnits(StringMap _sources)
m_sourceCodes = std::move(_sources);
}
ReadCallback::Result FileReader::readFile(string const& _kind, string const& _sourceUnitName)
ReadCallback::Result FileReader::readFile(std::string const& _kind, std::string const& _sourceUnitName)
{
try
{
if (_kind != ReadCallback::kindString(ReadCallback::Kind::ReadFile))
solAssert(false, "ReadFile callback used as callback kind " + _kind);
string strippedSourceUnitName = _sourceUnitName;
std::string strippedSourceUnitName = _sourceUnitName;
if (strippedSourceUnitName.find("file://") == 0)
strippedSourceUnitName.erase(0, 7);
vector<boost::filesystem::path> candidates;
vector<reference_wrapper<boost::filesystem::path>> prefixes = {m_basePath};
prefixes += (m_includePaths | ranges::to<vector<reference_wrapper<boost::filesystem::path>>>);
std::vector<boost::filesystem::path> candidates;
std::vector<std::reference_wrapper<boost::filesystem::path>> prefixes = {m_basePath};
prefixes += (m_includePaths | ranges::to<std::vector<std::reference_wrapper<boost::filesystem::path>>>);
for (auto const& prefix: prefixes)
{
@ -183,9 +179,9 @@ ReadCallback::Result FileReader::readFile(string const& _kind, string const& _so
}
}
string FileReader::cliPathToSourceUnitName(boost::filesystem::path const& _cliPath) const
std::string FileReader::cliPathToSourceUnitName(boost::filesystem::path const& _cliPath) const
{
vector<boost::filesystem::path> prefixes = {m_basePath.empty() ? normalizeCLIPathForVFS(".") : m_basePath};
std::vector<boost::filesystem::path> prefixes = {m_basePath.empty() ? normalizeCLIPathForVFS(".") : m_basePath};
prefixes += m_includePaths;
boost::filesystem::path normalizedPath = normalizeCLIPathForVFS(_cliPath);
@ -200,17 +196,17 @@ string FileReader::cliPathToSourceUnitName(boost::filesystem::path const& _cliPa
return normalizedPath.generic_string();
}
map<string, FileReader::FileSystemPathSet> FileReader::detectSourceUnitNameCollisions(FileSystemPathSet const& _cliPaths) const
std::map<std::string, FileReader::FileSystemPathSet> FileReader::detectSourceUnitNameCollisions(FileSystemPathSet const& _cliPaths) const
{
map<string, FileReader::FileSystemPathSet> nameToPaths;
std::map<std::string, FileReader::FileSystemPathSet> nameToPaths;
for (boost::filesystem::path const& cliPath: _cliPaths)
{
string sourceUnitName = cliPathToSourceUnitName(cliPath);
std::string sourceUnitName = cliPathToSourceUnitName(cliPath);
boost::filesystem::path normalizedPath = normalizeCLIPathForVFS(cliPath);
nameToPaths[sourceUnitName].insert(normalizedPath);
}
map<string, FileReader::FileSystemPathSet> collisions;
std::map<std::string, FileReader::FileSystemPathSet> collisions;
for (auto&& [sourceUnitName, cliPaths]: nameToPaths)
if (cliPaths.size() >= 2)
collisions[sourceUnitName] = std::move(cliPaths);
@ -377,7 +373,7 @@ bool FileReader::hasDotDotSegments(boost::filesystem::path const& _path)
bool FileReader::isUNCPath(boost::filesystem::path const& _path)
{
string rootName = _path.root_name().string();
std::string rootName = _path.root_name().string();
return (
rootName.size() == 2 ||

View File

@ -37,7 +37,6 @@
#include <map>
#include <memory>
using namespace std;
using namespace solidity;
using namespace solidity::evmasm;
using namespace solidity::frontend;
@ -45,16 +44,16 @@ using namespace solidity::langutil;
GasEstimator::GasConsumption GasEstimator::functionalEstimation(
AssemblyItems const& _items,
string const& _signature
std::string const& _signature
) const
{
auto state = make_shared<KnownState>();
auto state = std::make_shared<KnownState>();
if (!_signature.empty())
{
ExpressionClasses& classes = state->expressionClasses();
using Id = ExpressionClasses::Id;
using Ids = vector<Id>;
using Ids = std::vector<Id>;
Id hashValue = classes.find(u256(util::selectorFromSignatureU32(_signature)));
Id calldata = classes.find(Instruction::CALLDATALOAD, Ids{classes.find(u256(0))});
if (!m_evmVersion.hasBitwiseShifting())
@ -88,7 +87,7 @@ GasEstimator::GasConsumption GasEstimator::functionalEstimation(
FunctionDefinition const& _function
) const
{
auto state = make_shared<KnownState>();
auto state = std::make_shared<KnownState>();
unsigned parametersSize = CompilerUtils::sizeOnStack(_function.parameters());
if (parametersSize > 16)
@ -104,13 +103,13 @@ GasEstimator::GasConsumption GasEstimator::functionalEstimation(
return PathGasMeter::estimateMax(_items, m_evmVersion, _offset, state);
}
set<ASTNode const*> GasEstimator::finestNodesAtLocation(
vector<ASTNode const*> const& _roots
std::set<ASTNode const*> GasEstimator::finestNodesAtLocation(
std::vector<ASTNode const*> const& _roots
)
{
map<SourceLocation, ASTNode const*> locations;
set<ASTNode const*> nodes;
SimpleASTVisitor visitor(function<bool(ASTNode const&)>(), [&](ASTNode const& _n)
std::map<SourceLocation, ASTNode const*> locations;
std::set<ASTNode const*> nodes;
SimpleASTVisitor visitor(std::function<bool(ASTNode const&)>(), [&](ASTNode const& _n)
{
if (!locations.count(_n.location()))
{

View File

@ -19,29 +19,20 @@
#include <libsolutil/CommonIO.h>
#include <liblangutil/Exceptions.h>
using std::equal;
using std::find;
using std::move;
using std::nullopt;
using std::optional;
using std::string;
using std::string_view;
using std::vector;
namespace solidity::frontend
{
void ImportRemapper::setRemappings(vector<Remapping> _remappings)
void ImportRemapper::setRemappings(std::vector<Remapping> _remappings)
{
for (auto const& remapping: _remappings)
solAssert(!remapping.prefix.empty(), "");
m_remappings = std::move(_remappings);
}
SourceUnitName ImportRemapper::apply(ImportPath const& _path, string const& _context) const
SourceUnitName ImportRemapper::apply(ImportPath const& _path, std::string const& _context) const
{
// Try to find the longest prefix match in all remappings that are active in the current context.
auto isPrefixOf = [](string const& _a, string const& _b)
auto isPrefixOf = [](std::string const& _a, std::string const& _b)
{
if (_a.length() > _b.length())
return false;
@ -50,12 +41,12 @@ SourceUnitName ImportRemapper::apply(ImportPath const& _path, string const& _con
size_t longestPrefix = 0;
size_t longestContext = 0;
string bestMatchTarget;
std::string bestMatchTarget;
for (auto const& redir: m_remappings)
{
string context = util::sanitizePath(redir.context);
string prefix = util::sanitizePath(redir.prefix);
std::string context = util::sanitizePath(redir.context);
std::string prefix = util::sanitizePath(redir.prefix);
// Skip if current context is closer
if (context.length() < longestContext)
@ -74,32 +65,32 @@ SourceUnitName ImportRemapper::apply(ImportPath const& _path, string const& _con
longestPrefix = prefix.length();
bestMatchTarget = util::sanitizePath(redir.target);
}
string path = bestMatchTarget;
path.append(_path.begin() + static_cast<string::difference_type>(longestPrefix), _path.end());
std::string path = bestMatchTarget;
path.append(_path.begin() + static_cast<std::string::difference_type>(longestPrefix), _path.end());
return path;
}
bool ImportRemapper::isRemapping(string_view _input)
bool ImportRemapper::isRemapping(std::string_view _input)
{
return _input.find("=") != string::npos;
return _input.find("=") != std::string::npos;
}
optional<ImportRemapper::Remapping> ImportRemapper::parseRemapping(string_view _input)
std::optional<ImportRemapper::Remapping> ImportRemapper::parseRemapping(std::string_view _input)
{
auto equals = find(_input.cbegin(), _input.cend(), '=');
auto equals = std::find(_input.cbegin(), _input.cend(), '=');
if (equals == _input.end())
return nullopt;
return std::nullopt;
auto const colon = find(_input.cbegin(), equals, ':');
auto const colon = std::find(_input.cbegin(), equals, ':');
Remapping remapping{
(colon == equals ? "" : string(_input.cbegin(), colon)),
(colon == equals ? string(_input.cbegin(), equals) : string(colon + 1, equals)),
string(equals + 1, _input.cend()),
(colon == equals ? "" : std::string(_input.cbegin(), colon)),
(colon == equals ? std::string(_input.cbegin(), equals) : std::string(colon + 1, equals)),
std::string(equals + 1, _input.cend()),
};
if (remapping.prefix.empty())
return nullopt;
return std::nullopt;
return remapping;
}

View File

@ -30,8 +30,6 @@
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
@ -46,7 +44,7 @@ Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef)
auto constructorDefinition(_contractDef.constructor());
if (constructorDefinition)
{
string const value = extractDoc(constructorDefinition->annotation().docTags, "notice");
std::string const value = extractDoc(constructorDefinition->annotation().docTags, "notice");
if (!value.empty())
{
// add the constructor, only if we have any documentation to add
@ -56,14 +54,14 @@ Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef)
}
}
string notice = extractDoc(_contractDef.annotation().docTags, "notice");
std::string notice = extractDoc(_contractDef.annotation().docTags, "notice");
if (!notice.empty())
doc["notice"] = Json::Value(notice);
for (auto const& it: _contractDef.interfaceFunctions())
if (it.second->hasDeclaration())
{
string value;
std::string value;
if (auto const* f = dynamic_cast<FunctionDefinition const*>(&it.second->declaration()))
value = extractDoc(f->annotation().docTags, "notice");
@ -80,14 +78,14 @@ Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef)
for (auto const& event: uniqueInterfaceEvents(_contractDef))
{
string value = extractDoc(event->annotation().docTags, "notice");
std::string value = extractDoc(event->annotation().docTags, "notice");
if (!value.empty())
doc["events"][event->functionType(true)->externalSignature()]["notice"] = value;
}
for (auto const& error: _contractDef.interfaceErrors())
{
string value = extractDoc(error->annotation().docTags, "notice");
std::string value = extractDoc(error->annotation().docTags, "notice");
if (!value.empty())
{
Json::Value errorDoc{Json::objectValue};
@ -152,7 +150,7 @@ Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef)
if (auto devDoc = devDocumentation(varDecl->annotation().docTags); !devDoc.empty())
doc["stateVariables"][varDecl->name()] = devDoc;
auto const assignIfNotEmpty = [&](string const& _name, Json::Value const& _content)
auto const assignIfNotEmpty = [&](std::string const& _name, Json::Value const& _content)
{
if (!_content.empty())
doc["stateVariables"][varDecl->name()][_name] = _content;
@ -178,7 +176,7 @@ Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef)
return doc;
}
Json::Value Natspec::extractReturnParameterDocs(std::multimap<std::string, DocTag> const& _tags, vector<string> const& _returnParameterNames)
Json::Value Natspec::extractReturnParameterDocs(std::multimap<std::string, DocTag> const& _tags, std::vector<std::string> const& _returnParameterNames)
{
Json::Value jsonReturn{Json::objectValue};
auto returnDocs = _tags.equal_range("return");
@ -188,8 +186,8 @@ Json::Value Natspec::extractReturnParameterDocs(std::multimap<std::string, DocTa
size_t n = 0;
for (auto i = returnDocs.first; i != returnDocs.second; i++)
{
string paramName = _returnParameterNames.at(n);
string content = i->second.content;
std::string paramName = _returnParameterNames.at(n);
std::string content = i->second.content;
if (paramName.empty())
paramName = "_" + std::to_string(n);
@ -209,18 +207,18 @@ Json::Value Natspec::extractReturnParameterDocs(std::multimap<std::string, DocTa
return jsonReturn;
}
string Natspec::extractDoc(multimap<string, DocTag> const& _tags, string const& _name)
std::string Natspec::extractDoc(std::multimap<std::string, DocTag> const& _tags, std::string const& _name)
{
string value;
std::string value;
auto range = _tags.equal_range(_name);
for (auto i = range.first; i != range.second; i++)
value += i->second.content;
return value;
}
Json::Value Natspec::extractCustomDoc(multimap<string, DocTag> const& _tags)
Json::Value Natspec::extractCustomDoc(std::multimap<std::string, DocTag> const& _tags)
{
std::map<string, string> concatenated;
std::map<std::string, std::string> concatenated;
for (auto const& [tag, value]: _tags)
if (boost::starts_with(tag, "custom"))
concatenated[tag] += value.content;
@ -255,9 +253,9 @@ Json::Value Natspec::devDocumentation(std::multimap<std::string, DocTag> const&
return json;
}
vector<EventDefinition const*> Natspec::uniqueInterfaceEvents(ContractDefinition const& _contract)
std::vector<EventDefinition const*> Natspec::uniqueInterfaceEvents(ContractDefinition const& _contract)
{
auto eventSignature = [](EventDefinition const* _event) -> string {
auto eventSignature = [](EventDefinition const* _event) -> std::string {
FunctionType const* functionType = _event->functionType(true);
solAssert(functionType, "");
return functionType->externalSignature();
@ -267,13 +265,13 @@ vector<EventDefinition const*> Natspec::uniqueInterfaceEvents(ContractDefinitio
return eventSignature(_lhs) < eventSignature(_rhs);
};
set<EventDefinition const*, decltype(compareBySignature)> uniqueEvents{compareBySignature};
std::set<EventDefinition const*, decltype(compareBySignature)> uniqueEvents{compareBySignature};
// Insert events defined in the contract first so that in case of a conflict
// they're the ones that get selected.
uniqueEvents += _contract.definedInterfaceEvents();
set<EventDefinition const*, decltype(compareBySignature)> filteredUsedEvents{compareBySignature};
set<string> usedSignatures;
std::set<EventDefinition const*, decltype(compareBySignature)> filteredUsedEvents{compareBySignature};
std::set<std::string> usedSignatures;
for (EventDefinition const* event: _contract.usedInterfaceEvents())
{
auto&& [eventIt, eventInserted] = filteredUsedEvents.insert(event);
@ -283,5 +281,5 @@ vector<EventDefinition const*> Natspec::uniqueInterfaceEvents(ContractDefinitio
}
uniqueEvents += filteredUsedEvents;
return util::convertContainer<vector<EventDefinition const*>>(std::move(uniqueEvents));
return util::convertContainer<std::vector<EventDefinition const*>>(std::move(uniqueEvents));
}

View File

@ -59,7 +59,7 @@ struct OptimiserSettings
"]"
"jmul[jul] VcTOcul jmul"; // Make source short and pretty
static char constexpr DefaultYulOptimiserCleanupSteps[] = "fDnTOc";
static char constexpr DefaultYulOptimiserCleanupSteps[] = "fDnTOcmu";
/// No optimisations at all - not recommended.
static OptimiserSettings none()

View File

@ -33,14 +33,13 @@
using solidity::langutil::InternalCompilerError;
using solidity::util::errinfo_comment;
using namespace std;
namespace solidity::frontend
{
SMTSolverCommand::SMTSolverCommand(string _solverCmd) : m_solverCmd(_solverCmd) {}
SMTSolverCommand::SMTSolverCommand(std::string _solverCmd) : m_solverCmd(_solverCmd) {}
ReadCallback::Result SMTSolverCommand::solve(string const& _kind, string const& _query)
ReadCallback::Result SMTSolverCommand::solve(std::string const& _kind, std::string const& _query)
{
try
{
@ -66,8 +65,8 @@ ReadCallback::Result SMTSolverCommand::solve(string const& _kind, string const&
boost::process::std_out > pipe
);
vector<string> data;
string line;
std::vector<std::string> data;
std::string line;
while (eld.running() && std::getline(pipe, line))
if (!line.empty())
data.push_back(line);

View File

@ -44,20 +44,20 @@
#include <algorithm>
#include <optional>
using namespace std;
using namespace solidity;
using namespace solidity::yul;
using namespace solidity::frontend;
using namespace solidity::langutil;
using namespace std::string_literals;
namespace
{
Json::Value formatError(
Error::Type _type,
string const& _component,
string const& _message,
string const& _formattedMessage = "",
std::string const& _component,
std::string const& _message,
std::string const& _formattedMessage = "",
Json::Value const& _sourceLocation = Json::Value(),
Json::Value const& _secondarySourceLocation = Json::Value()
)
@ -75,7 +75,7 @@ Json::Value formatError(
return error;
}
Json::Value formatFatalError(Error::Type _type, string const& _message)
Json::Value formatFatalError(Error::Type _type, std::string const& _message)
{
Json::Value output{Json::objectValue};
output["errors"] = Json::arrayValue;
@ -114,22 +114,21 @@ Json::Value formatErrorWithException(
CharStreamProvider const& _charStreamProvider,
util::Exception const& _exception,
Error::Type _type,
string const& _component,
string const& _message,
optional<ErrorId> _errorId = nullopt
std::string const& _component,
std::string const& _message,
std::optional<ErrorId> _errorId = std::nullopt
)
{
string message;
std::string message;
// TODO: consider enabling color
string formattedMessage = SourceReferenceFormatter::formatExceptionInformation(
std::string formattedMessage = SourceReferenceFormatter::formatExceptionInformation(
_exception,
_type,
_charStreamProvider,
false, // colored
false // _withErrorIds
false // colored
);
if (string const* description = _exception.comment())
if (std::string const* description = _exception.comment())
message = ((_message.length() > 0) ? (_message + ":") : "") + *description;
else
message = _message;
@ -144,20 +143,20 @@ Json::Value formatErrorWithException(
);
if (_errorId)
error["errorCode"] = to_string(_errorId.value().error);
error["errorCode"] = std::to_string(_errorId.value().error);
return error;
}
map<string, set<string>> requestedContractNames(Json::Value const& _outputSelection)
std::map<std::string, std::set<std::string>> requestedContractNames(Json::Value const& _outputSelection)
{
map<string, set<string>> contracts;
std::map<std::string, std::set<std::string>> contracts;
for (auto const& sourceName: _outputSelection.getMemberNames())
{
string key = (sourceName == "*") ? "" : sourceName;
std::string key = (sourceName == "*") ? "" : sourceName;
for (auto const& contractName: _outputSelection[sourceName].getMemberNames())
{
string value = (contractName == "*") ? "" : contractName;
std::string value = (contractName == "*") ? "" : contractName;
contracts[key].insert(value);
}
}
@ -165,7 +164,7 @@ map<string, set<string>> requestedContractNames(Json::Value const& _outputSelect
}
/// Returns true iff @a _hash (hex with 0x prefix) is the Keccak256 hash of the binary data in @a _content.
bool hashMatchesContent(string const& _hash, string const& _content)
bool hashMatchesContent(std::string const& _hash, std::string const& _content)
{
try
{
@ -177,12 +176,12 @@ bool hashMatchesContent(string const& _hash, string const& _content)
}
}
bool isArtifactRequested(Json::Value const& _outputSelection, string const& _artifact, bool _wildcardMatchesExperimental)
bool isArtifactRequested(Json::Value const& _outputSelection, std::string const& _artifact, bool _wildcardMatchesExperimental)
{
static set<string> experimental{"ir", "irAst", "irOptimized", "irOptimizedAst"};
static std::set<std::string> experimental{"ir", "irAst", "irOptimized", "irOptimizedAst"};
for (auto const& selectedArtifactJson: _outputSelection)
{
string const& selectedArtifact = selectedArtifactJson.asString();
std::string const& selectedArtifact = selectedArtifactJson.asString();
if (
_artifact == selectedArtifact ||
boost::algorithm::starts_with(_artifact, selectedArtifact + ".")
@ -211,17 +210,17 @@ bool isArtifactRequested(Json::Value const& _outputSelection, string const& _art
///
/// @TODO optimise this. Perhaps flatten the structure upfront.
///
bool isArtifactRequested(Json::Value const& _outputSelection, string const& _file, string const& _contract, string const& _artifact, bool _wildcardMatchesExperimental)
bool isArtifactRequested(Json::Value const& _outputSelection, std::string const& _file, std::string const& _contract, std::string const& _artifact, bool _wildcardMatchesExperimental)
{
if (!_outputSelection.isObject())
return false;
for (auto const& file: { _file, string("*") })
for (auto const& file: { _file, std::string("*") })
if (_outputSelection.isMember(file) && _outputSelection[file].isObject())
{
/// For SourceUnit-level targets (such as AST) only allow empty name, otherwise
/// for Contract-level targets try both contract name and wildcard
vector<string> contracts{ _contract };
std::vector<std::string> contracts{ _contract };
if (!_contract.empty())
contracts.emplace_back("*");
for (auto const& contract: contracts)
@ -236,7 +235,7 @@ bool isArtifactRequested(Json::Value const& _outputSelection, string const& _fil
return false;
}
bool isArtifactRequested(Json::Value const& _outputSelection, string const& _file, string const& _contract, vector<string> const& _artifacts, bool _wildcardMatchesExperimental)
bool isArtifactRequested(Json::Value const& _outputSelection, std::string const& _file, std::string const& _contract, std::vector<std::string> const& _artifacts, bool _wildcardMatchesExperimental)
{
for (auto const& artifact: _artifacts)
if (isArtifactRequested(_outputSelection, _file, _contract, artifact, _wildcardMatchesExperimental))
@ -245,10 +244,10 @@ bool isArtifactRequested(Json::Value const& _outputSelection, string const& _fil
}
/// @returns all artifact names of the EVM object, either for creation or deploy time.
vector<string> evmObjectComponents(string const& _objectKind)
std::vector<std::string> evmObjectComponents(std::string const& _objectKind)
{
solAssert(_objectKind == "bytecode" || _objectKind == "deployedBytecode", "");
vector<string> components{"", ".object", ".opcodes", ".sourceMap", ".functionDebugData", ".generatedSources", ".linkReferences"};
std::vector<std::string> components{"", ".object", ".opcodes", ".sourceMap", ".functionDebugData", ".generatedSources", ".linkReferences"};
if (_objectKind == "deployedBytecode")
components.push_back(".immutableReferences");
return util::applyMap(components, [&](auto const& _s) { return "evm." + _objectKind + _s; });
@ -261,7 +260,7 @@ bool isBinaryRequested(Json::Value const& _outputSelection)
return false;
// This does not include "evm.methodIdentifiers" on purpose!
static vector<string> const outputsThatRequireBinaries = vector<string>{
static std::vector<std::string> const outputsThatRequireBinaries = std::vector<std::string>{
"*",
"ir", "irAst", "irOptimized", "irOptimizedAst",
"evm.gasEstimates", "evm.legacyAssembly", "evm.assembly"
@ -281,7 +280,7 @@ bool isEvmBytecodeRequested(Json::Value const& _outputSelection)
if (!_outputSelection.isObject())
return false;
static vector<string> const outputsThatRequireEvmBinaries = vector<string>{
static std::vector<std::string> const outputsThatRequireEvmBinaries = std::vector<std::string>{
"*",
"evm.gasEstimates", "evm.legacyAssembly", "evm.assembly"
} + evmObjectComponents("bytecode") + evmObjectComponents("deployedBytecode");
@ -321,13 +320,13 @@ Json::Value formatLinkReferences(std::map<size_t, std::string> const& linkRefere
for (auto const& ref: linkReferences)
{
string const& fullname = ref.second;
std::string const& fullname = ref.second;
// If the link reference does not contain a colon, assume that the file name is missing and
// the whole string represents the library name.
size_t colon = fullname.rfind(':');
string file = (colon != string::npos ? fullname.substr(0, colon) : "");
string name = (colon != string::npos ? fullname.substr(colon + 1) : fullname);
std::string file = (colon != std::string::npos ? fullname.substr(0, colon) : "");
std::string name = (colon != std::string::npos ? fullname.substr(colon + 1) : fullname);
Json::Value fileObject = ret.get(file, Json::objectValue);
Json::Value libraryArray = fileObject.get(name, Json::arrayValue);
@ -344,7 +343,7 @@ Json::Value formatLinkReferences(std::map<size_t, std::string> const& linkRefere
return ret;
}
Json::Value formatImmutableReferences(map<u256, pair<string, vector<size_t>>> const& _immutableReferences)
Json::Value formatImmutableReferences(std::map<u256, std::pair<std::string, std::vector<size_t>>> const& _immutableReferences)
{
Json::Value ret{Json::objectValue};
@ -368,10 +367,10 @@ Json::Value formatImmutableReferences(map<u256, pair<string, vector<size_t>>> co
Json::Value collectEVMObject(
langutil::EVMVersion _evmVersion,
evmasm::LinkerObject const& _object,
string const* _sourceMap,
std::string const* _sourceMap,
Json::Value _generatedSources,
bool _runtimeObject,
function<bool(string)> const& _artifactRequested
std::function<bool(std::string)> const& _artifactRequested
)
{
Json::Value output{Json::objectValue};
@ -392,7 +391,7 @@ Json::Value collectEVMObject(
return output;
}
std::optional<Json::Value> checkKeys(Json::Value const& _input, set<string> const& _keys, string const& _name)
std::optional<Json::Value> checkKeys(Json::Value const& _input, std::set<std::string> const& _keys, std::string const& _name)
{
if (!!_input && !_input.isObject())
return formatFatalError(Error::Type::JSONError, "\"" + _name + "\" must be an object");
@ -406,43 +405,43 @@ std::optional<Json::Value> checkKeys(Json::Value const& _input, set<string> cons
std::optional<Json::Value> checkRootKeys(Json::Value const& _input)
{
static set<string> keys{"auxiliaryInput", "language", "settings", "sources"};
static std::set<std::string> keys{"auxiliaryInput", "language", "settings", "sources"};
return checkKeys(_input, keys, "root");
}
std::optional<Json::Value> checkSourceKeys(Json::Value const& _input, string const& _name)
std::optional<Json::Value> checkSourceKeys(Json::Value const& _input, std::string const& _name)
{
static set<string> keys{"content", "keccak256", "urls"};
static std::set<std::string> keys{"content", "keccak256", "urls"};
return checkKeys(_input, keys, "sources." + _name);
}
std::optional<Json::Value> checkAuxiliaryInputKeys(Json::Value const& _input)
{
static set<string> keys{"smtlib2responses"};
static std::set<std::string> keys{"smtlib2responses"};
return checkKeys(_input, keys, "auxiliaryInput");
}
std::optional<Json::Value> checkSettingsKeys(Json::Value const& _input)
{
static set<string> keys{"parserErrorRecovery", "debug", "evmVersion", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"};
static std::set<std::string> keys{"debug", "evmVersion", "libraries", "metadata", "modelChecker", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"};
return checkKeys(_input, keys, "settings");
}
std::optional<Json::Value> checkModelCheckerSettingsKeys(Json::Value const& _input)
{
static set<string> keys{"bmcLoopIterations", "contracts", "divModNoSlacks", "engine", "extCalls", "invariants", "printQuery", "showProvedSafe", "showUnproved", "showUnsupported", "solvers", "targets", "timeout"};
static std::set<std::string> keys{"bmcLoopIterations", "contracts", "divModNoSlacks", "engine", "extCalls", "invariants", "printQuery", "showProvedSafe", "showUnproved", "showUnsupported", "solvers", "targets", "timeout"};
return checkKeys(_input, keys, "modelChecker");
}
std::optional<Json::Value> checkOptimizerKeys(Json::Value const& _input)
{
static set<string> keys{"details", "enabled", "runs"};
static std::set<std::string> keys{"details", "enabled", "runs"};
return checkKeys(_input, keys, "settings.optimizer");
}
std::optional<Json::Value> checkOptimizerDetailsKeys(Json::Value const& _input)
{
static set<string> keys{"peephole", "inliner", "jumpdestRemover", "orderLiterals", "deduplicate", "cse", "constantOptimizer", "yul", "yulDetails"};
static std::set<std::string> keys{"peephole", "inliner", "jumpdestRemover", "orderLiterals", "deduplicate", "cse", "constantOptimizer", "yul", "yulDetails"};
return checkKeys(_input, keys, "settings.optimizer.details");
}
@ -457,7 +456,7 @@ std::optional<Json::Value> checkOptimizerDetail(Json::Value const& _details, std
return {};
}
std::optional<Json::Value> checkOptimizerDetailSteps(Json::Value const& _details, std::string const& _name, string& _optimiserSetting, string& _cleanupSetting)
std::optional<Json::Value> checkOptimizerDetailSteps(Json::Value const& _details, std::string const& _name, std::string& _optimiserSetting, std::string& _cleanupSetting)
{
if (_details.isMember(_name))
{
@ -475,11 +474,11 @@ std::optional<Json::Value> checkOptimizerDetailSteps(Json::Value const& _details
);
}
string const fullSequence = _details[_name].asString();
std::string const fullSequence = _details[_name].asString();
auto const delimiterPos = fullSequence.find(":");
_optimiserSetting = fullSequence.substr(0, delimiterPos);
if (delimiterPos != string::npos)
if (delimiterPos != std::string::npos)
_cleanupSetting = fullSequence.substr(delimiterPos + 1);
else
solAssert(_cleanupSetting == OptimiserSettings::DefaultYulOptimiserCleanupSteps);
@ -500,11 +499,11 @@ std::optional<Json::Value> checkMetadataKeys(Json::Value const& _input)
if (_input.isMember("useLiteralContent") && !_input["useLiteralContent"].isBool())
return formatFatalError(Error::Type::JSONError, "\"settings.metadata.useLiteralContent\" must be Boolean");
static set<string> hashes{"ipfs", "bzzr1", "none"};
static std::set<std::string> hashes{"ipfs", "bzzr1", "none"};
if (_input.isMember("bytecodeHash") && !hashes.count(_input["bytecodeHash"].asString()))
return formatFatalError(Error::Type::JSONError, "\"settings.metadata.bytecodeHash\" must be \"ipfs\", \"bzzr1\" or \"none\"");
}
static set<string> keys{"appendCBOR", "useLiteralContent", "bytecodeHash"};
static std::set<std::string> keys{"appendCBOR", "useLiteralContent", "bytecodeHash"};
return checkKeys(_input, keys, "settings.metadata");
}
@ -646,7 +645,7 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
{
for (auto const& sourceName: sources.getMemberNames())
{
string hash;
std::string hash;
if (auto result = checkSourceKeys(sources[sourceName], sourceName))
return *result;
@ -656,7 +655,7 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
if (sources[sourceName]["content"].isString())
{
string content = sources[sourceName]["content"].asString();
std::string content = sources[sourceName]["content"].asString();
if (!hash.empty() && !hashMatchesContent(hash, content))
ret.errors.append(formatError(
Error::Type::IOError,
@ -673,7 +672,7 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
Error::Type::JSONError, "No import callback supplied, but URL is requested."
);
vector<string> failures;
std::vector<std::string> failures;
bool found = false;
for (auto const& url: sources[sourceName]["urls"])
@ -774,13 +773,6 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
ret.stopAfter = CompilerStack::State::Parsed;
}
if (settings.isMember("parserErrorRecovery"))
{
if (!settings["parserErrorRecovery"].isBool())
return formatFatalError(Error::Type::JSONError, "\"settings.parserErrorRecovery\" must be a Boolean.");
ret.parserErrorRecovery = settings["parserErrorRecovery"].asBool();
}
if (settings.isMember("viaIR"))
{
if (!settings["viaIR"].isBool())
@ -833,11 +825,11 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
if (!settings["debug"]["debugInfo"].isArray())
return formatFatalError(Error::Type::JSONError, "settings.debug.debugInfo must be an array.");
vector<string> components;
std::vector<std::string> components;
for (Json::Value const& arrayValue: settings["debug"]["debugInfo"])
components.push_back(arrayValue.asString());
optional<DebugInfoSelection> debugInfoSelection = DebugInfoSelection::fromComponents(
std::optional<DebugInfoSelection> debugInfoSelection = DebugInfoSelection::fromComponents(
components,
true /* _acceptWildcards */
);
@ -888,7 +880,7 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
{
if (!jsonSourceName[library].isString())
return formatFatalError(Error::Type::JSONError, "Library address must be a string.");
string address = jsonSourceName[library].asString();
std::string address = jsonSourceName[library].asString();
if (!boost::starts_with(address, "0x"))
return formatFatalError(
@ -970,7 +962,7 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
if (!sources.isObject() && !sources.isNull())
return formatFatalError(Error::Type::JSONError, "settings.modelChecker.contracts is not a JSON object.");
map<string, set<string>> sourceContracts;
std::map<std::string, std::set<std::string>> sourceContracts;
for (auto const& source: sources.getMemberNames())
{
if (source.empty())
@ -1139,14 +1131,14 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
return {std::move(ret)};
}
map<string, Json::Value> StandardCompiler::parseAstFromInput(StringMap const& _sources)
std::map<std::string, Json::Value> StandardCompiler::parseAstFromInput(StringMap const& _sources)
{
map<string, Json::Value> sourceJsons;
std::map<std::string, Json::Value> sourceJsons;
for (auto const& [sourceName, sourceCode]: _sources)
{
Json::Value ast;
astAssert(util::jsonParseStrict(sourceCode, ast), "Input file could not be parsed to JSON");
string astKey = ast.isMember("ast") ? "ast" : "AST";
std::string astKey = ast.isMember("ast") ? "ast" : "AST";
astAssert(ast.isMember(astKey), "astkey is not member");
astAssert(ast[astKey]["nodeType"].asString() == "SourceUnit", "Top-level node should be a 'SourceUnit'");
@ -1167,7 +1159,6 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
compilerStack.addSMTLib2Response(smtLib2Response.first, smtLib2Response.second);
compilerStack.setViaIR(_inputsAndSettings.viaIR);
compilerStack.setEVMVersion(_inputsAndSettings.evmVersion);
compilerStack.setParserErrorRecovery(_inputsAndSettings.parserErrorRecovery);
compilerStack.setRemappings(std::move(_inputsAndSettings.remappings));
compilerStack.setOptimiserSettings(std::move(_inputsAndSettings.optimiserSettings));
compilerStack.setRevertStringBehaviour(_inputsAndSettings.revertStrings);
@ -1318,21 +1309,18 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
}
bool parsingSuccess = compilerStack.state() >= CompilerStack::State::Parsed;
bool analysisPerformed = compilerStack.state() >= CompilerStack::State::AnalysisPerformed;
bool analysisSuccess = compilerStack.state() >= CompilerStack::State::AnalysisSuccessful;
bool compilationSuccess = compilerStack.state() == CompilerStack::State::CompilationSuccessful;
if (compilerStack.hasError() && !_inputsAndSettings.parserErrorRecovery)
analysisPerformed = false;
// If analysis fails, the artifacts inside CompilerStack are potentially incomplete and must not be returned.
// Note that not completing analysis due to stopAfter does not count as a failure. It's neither failure nor success.
bool analysisFailed = !analysisPerformed && _inputsAndSettings.stopAfter >= CompilerStack::State::AnalysisPerformed;
bool analysisFailed = !analysisSuccess && _inputsAndSettings.stopAfter >= CompilerStack::State::AnalysisSuccessful;
bool compilationFailed = !compilationSuccess && binariesRequested;
/// Inconsistent state - stop here to receive error reports from users
if (
(compilationFailed || !analysisPerformed) &&
(errors.empty() && _inputsAndSettings.stopAfter >= CompilerStack::State::AnalysisPerformed)
(compilationFailed || analysisFailed || !parsingSuccess) &&
errors.empty()
)
return formatFatalError(Error::Type::InternalCompilerError, "No error reported, but compilation failed.");
@ -1342,15 +1330,17 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
output["errors"] = std::move(errors);
if (!compilerStack.unhandledSMTLib2Queries().empty())
for (string const& query: compilerStack.unhandledSMTLib2Queries())
for (std::string const& query: compilerStack.unhandledSMTLib2Queries())
output["auxiliaryInputRequested"]["smtlib2queries"]["0x" + util::keccak256(query).hex()] = query;
bool const wildcardMatchesExperimental = false;
output["sources"] = Json::objectValue;
unsigned sourceIndex = 0;
if (parsingSuccess && !analysisFailed && (!compilerStack.hasError() || _inputsAndSettings.parserErrorRecovery))
for (string const& sourceName: compilerStack.sourceNames())
// NOTE: A case that will pass `parsingSuccess && !analysisFailed` but not `analysisSuccess` is
// stopAfter: parsing with no parsing errors.
if (parsingSuccess && !analysisFailed)
for (std::string const& sourceName: compilerStack.sourceNames())
{
Json::Value sourceResult = Json::objectValue;
sourceResult["id"] = sourceIndex++;
@ -1360,12 +1350,12 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
}
Json::Value contractsOutput = Json::objectValue;
for (string const& contractName: analysisPerformed ? compilerStack.contractNames() : vector<string>())
for (std::string const& contractName: analysisSuccess ? compilerStack.contractNames() : std::vector<std::string>())
{
size_t colon = contractName.rfind(':');
solAssert(colon != string::npos, "");
string file = contractName.substr(0, colon);
string name = contractName.substr(colon + 1);
solAssert(colon != std::string::npos, "");
std::string file = contractName.substr(0, colon);
std::string name = contractName.substr(colon + 1);
// ABI, storage layout, documentation and metadata
Json::Value contractData(Json::objectValue);
@ -1414,7 +1404,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
compilerStack.sourceMapping(contractName),
compilerStack.generatedSources(contractName),
false,
[&](string const& _element) { return isArtifactRequested(
[&](std::string const& _element) { return isArtifactRequested(
_inputsAndSettings.outputSelection,
file,
name,
@ -1436,7 +1426,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
compilerStack.runtimeSourceMapping(contractName),
compilerStack.generatedSources(contractName, true),
true,
[&](string const& _element) { return isArtifactRequested(
[&](std::string const& _element) { return isArtifactRequested(
_inputsAndSettings.outputSelection,
file,
name,
@ -1513,8 +1503,8 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
_inputsAndSettings.debugInfoSelection.value() :
DebugInfoSelection::Default()
);
string const& sourceName = _inputsAndSettings.sources.begin()->first;
string const& sourceContents = _inputsAndSettings.sources.begin()->second;
std::string const& sourceName = _inputsAndSettings.sources.begin()->first;
std::string const& sourceContents = _inputsAndSettings.sources.begin()->second;
// Inconsistent state - stop here to receive error reports from users
if (!stack.parseAndAnalyze(sourceName, sourceContents) && stack.errors().empty())
@ -1531,7 +1521,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
{
for (auto const& error: stack.errors())
{
auto err = dynamic_pointer_cast<Error const>(error);
auto err = std::dynamic_pointer_cast<Error const>(error);
output["errors"].append(formatErrorWithException(
stack,
@ -1544,7 +1534,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
return output;
}
string contractName = stack.parserResult()->name.str();
std::string contractName = stack.parserResult()->name.str();
bool const wildcardMatchesExperimental = true;
if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, contractName, "ir", wildcardMatchesExperimental))
@ -1561,7 +1551,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
MachineAssemblyObject object;
MachineAssemblyObject deployedObject;
tie(object, deployedObject) = stack.assembleWithDeployed();
std::tie(object, deployedObject) = stack.assembleWithDeployed();
if (object.bytecode)
object.bytecode->link(_inputsAndSettings.libraries);
@ -1586,7 +1576,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
o.sourceMappings.get(),
Json::arrayValue,
isDeployed,
[&, kind = kind](string const& _element) { return isArtifactRequested(
[&, kind = kind](std::string const& _element) { return isArtifactRequested(
_inputsAndSettings.outputSelection,
sourceName,
contractName,
@ -1626,11 +1616,11 @@ Json::Value StandardCompiler::compile(Json::Value const& _input) noexcept
}
catch (Json::LogicError const& _exception)
{
return formatFatalError(Error::Type::InternalCompilerError, string("JSON logic exception: ") + _exception.what());
return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON logic exception: ") + _exception.what());
}
catch (Json::RuntimeError const& _exception)
{
return formatFatalError(Error::Type::InternalCompilerError, string("JSON runtime exception: ") + _exception.what());
return formatFatalError(Error::Type::InternalCompilerError, std::string("JSON runtime exception: ") + _exception.what());
}
catch (util::Exception const& _exception)
{
@ -1642,10 +1632,10 @@ Json::Value StandardCompiler::compile(Json::Value const& _input) noexcept
}
}
string StandardCompiler::compile(string const& _input) noexcept
std::string StandardCompiler::compile(std::string const& _input) noexcept
{
Json::Value input;
string errors;
std::string errors;
try
{
if (!util::jsonParseStrict(_input, input, &errors))
@ -1671,7 +1661,7 @@ string StandardCompiler::compile(string const& _input) noexcept
}
Json::Value StandardCompiler::formatFunctionDebugData(
map<string, evmasm::LinkerObject::FunctionDebugData> const& _debugInfo
std::map<std::string, evmasm::LinkerObject::FunctionDebugData> const& _debugInfo
)
{
Json::Value ret(Json::objectValue);

View File

@ -72,7 +72,6 @@ private:
{
std::string language;
Json::Value errors;
bool parserErrorRecovery = false;
CompilerStack::State stopAfter = CompilerStack::State::CompilationSuccessful;
std::map<std::string, std::string> sources;
std::map<util::h256, std::string> smtLib2Responses;

View File

@ -20,7 +20,6 @@
#include <libsolidity/ast/TypeProvider.h>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
@ -112,7 +111,7 @@ void StorageLayout::generate(Type const* _type)
solAssert(typeInfo.isMember("encoding"), "");
}
string StorageLayout::typeKeyName(Type const* _type)
std::string StorageLayout::typeKeyName(Type const* _type)
{
if (auto refType = dynamic_cast<ReferenceType const*>(_type))
return TypeProvider::withLocationIfReference(refType->location(), _type)->richIdentifier();

View File

@ -25,19 +25,17 @@
#include <solidity/BuildInfo.h>
using namespace std;
char const* solidity::frontend::VersionNumber = ETH_PROJECT_VERSION;
string const solidity::frontend::VersionString =
string(solidity::frontend::VersionNumber) +
(string(SOL_VERSION_PRERELEASE).empty() ? "" : "-" + string(SOL_VERSION_PRERELEASE)) +
(string(SOL_VERSION_BUILDINFO).empty() ? "" : "+" + string(SOL_VERSION_BUILDINFO));
std::string const solidity::frontend::VersionString =
std::string(solidity::frontend::VersionNumber) +
(std::string(SOL_VERSION_PRERELEASE).empty() ? "" : "-" + std::string(SOL_VERSION_PRERELEASE)) +
(std::string(SOL_VERSION_BUILDINFO).empty() ? "" : "+" + std::string(SOL_VERSION_BUILDINFO));
string const solidity::frontend::VersionStringStrict =
string(solidity::frontend::VersionNumber) +
(string(SOL_VERSION_PRERELEASE).empty() ? "" : "-" + string(SOL_VERSION_PRERELEASE)) +
(string(SOL_VERSION_COMMIT).empty() ? "" : "+" + string(SOL_VERSION_COMMIT));
std::string const solidity::frontend::VersionStringStrict =
std::string(solidity::frontend::VersionNumber) +
(std::string(SOL_VERSION_PRERELEASE).empty() ? "" : "-" + std::string(SOL_VERSION_PRERELEASE)) +
(std::string(SOL_VERSION_COMMIT).empty() ? "" : "+" + std::string(SOL_VERSION_COMMIT));
solidity::bytes const solidity::frontend::VersionCompactBytes = {
ETH_PROJECT_VERSION_MAJOR,
@ -45,4 +43,4 @@ solidity::bytes const solidity::frontend::VersionCompactBytes = {
ETH_PROJECT_VERSION_PATCH
};
bool const solidity::frontend::VersionIsRelease = string(SOL_VERSION_PRERELEASE).empty();
bool const solidity::frontend::VersionIsRelease = std::string(SOL_VERSION_PRERELEASE).empty();

View File

@ -23,9 +23,6 @@
namespace solidity::lsp
{
using namespace std;
using namespace solidity::lsp;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -35,16 +32,16 @@ namespace
struct MarkdownBuilder
{
stringstream result;
std::stringstream result;
MarkdownBuilder& solidityCode(string const& _code)
MarkdownBuilder& solidityCode(std::string const& _code)
{
auto constexpr SolidityLanguageId = "solidity";
result << "```" << SolidityLanguageId << '\n' << _code << "\n```\n\n";
return *this;
}
MarkdownBuilder& paragraph(string const& _text)
MarkdownBuilder& paragraph(std::string const& _text)
{
if (!_text.empty())
{

View File

@ -34,7 +34,6 @@
#include <fmt/format.h>
using namespace std;
using namespace solidity;
using namespace solidity::lsp;
using namespace solidity::frontend;
@ -54,11 +53,11 @@ void FileRepository::setIncludePaths(std::vector<boost::filesystem::path> _paths
m_includePaths = std::move(_paths);
}
string FileRepository::sourceUnitNameToUri(string const& _sourceUnitName) const
std::string FileRepository::sourceUnitNameToUri(std::string const& _sourceUnitName) const
{
regex const windowsDriveLetterPath("^[a-zA-Z]:/");
std::regex const windowsDriveLetterPath("^[a-zA-Z]:/");
auto const ensurePathIsUnixLike = [&](string inputPath) -> string {
auto const ensurePathIsUnixLike = [&](std::string inputPath) -> std::string {
if (!regex_search(inputPath, windowsDriveLetterPath))
return inputPath;
else
@ -86,13 +85,13 @@ string FileRepository::sourceUnitNameToUri(string const& _sourceUnitName) const
return "file:///" + _sourceUnitName;
}
string FileRepository::uriToSourceUnitName(string const& _path) const
std::string FileRepository::uriToSourceUnitName(std::string const& _path) const
{
lspRequire(boost::algorithm::starts_with(_path, "file://"), ErrorCode::InternalError, "URI must start with file://");
return stripFileUriSchemePrefix(_path);
}
void FileRepository::setSourceByUri(string const& _uri, string _source)
void FileRepository::setSourceByUri(std::string const& _uri, std::string _source)
{
// This is needed for uris outside the base path. It can lead to collisions,
// but we need to mostly rewrite this in a future version anyway.
@ -110,9 +109,9 @@ Result<boost::filesystem::path> FileRepository::tryResolvePath(std::string const
)
return boost::filesystem::path(_strippedSourceUnitName);
vector<boost::filesystem::path> candidates;
vector<reference_wrapper<boost::filesystem::path const>> prefixes = {m_basePath};
prefixes += (m_includePaths | ranges::to<vector<reference_wrapper<boost::filesystem::path const>>>);
std::vector<boost::filesystem::path> candidates;
std::vector<std::reference_wrapper<boost::filesystem::path const>> prefixes = {m_basePath};
prefixes += (m_includePaths | ranges::to<std::vector<std::reference_wrapper<boost::filesystem::path const>>>);
auto const defaultInclude = m_basePath / "node_modules";
if (m_includePaths.empty())
prefixes.emplace_back(defaultInclude);
@ -148,7 +147,7 @@ Result<boost::filesystem::path> FileRepository::tryResolvePath(std::string const
return candidates[0];
}
frontend::ReadCallback::Result FileRepository::readFile(string const& _kind, string const& _sourceUnitName)
frontend::ReadCallback::Result FileRepository::readFile(std::string const& _kind, std::string const& _sourceUnitName)
{
solAssert(
_kind == ReadCallback::kindString(ReadCallback::Kind::ReadFile),
@ -161,7 +160,7 @@ frontend::ReadCallback::Result FileRepository::readFile(string const& _kind, str
if (m_sourceCodes.count(_sourceUnitName))
return ReadCallback::Result{true, m_sourceCodes.at(_sourceUnitName)};
string const strippedSourceUnitName = stripFileUriSchemePrefix(_sourceUnitName);
std::string const strippedSourceUnitName = stripFileUriSchemePrefix(_sourceUnitName);
Result<boost::filesystem::path> const resolvedPath = tryResolvePath(strippedSourceUnitName);
if (!resolvedPath.message().empty())
return ReadCallback::Result{false, resolvedPath.message()};

View File

@ -30,7 +30,6 @@
using namespace solidity::frontend;
using namespace solidity::langutil;
using namespace solidity::lsp;
using namespace std;
void GotoDefinition::operator()(MessageID _id, Json::Value const& _args)
{
@ -38,7 +37,7 @@ void GotoDefinition::operator()(MessageID _id, Json::Value const& _args)
ASTNode const* sourceNode = m_server.astNodeAtSourceLocation(sourceUnitName, lineColumn);
vector<SourceLocation> locations;
std::vector<SourceLocation> locations;
if (auto const* expression = dynamic_cast<Expression const*>(sourceNode))
{
// Handles all expressions that can have one or more declaration annotation.
@ -56,7 +55,7 @@ void GotoDefinition::operator()(MessageID _id, Json::Value const& _args)
{
auto const& path = *importDirective->annotation().absolutePath;
if (fileRepository().sourceUnits().count(path))
locations.emplace_back(SourceLocation{0, 0, make_shared<string const>(path)});
locations.emplace_back(SourceLocation{0, 0, std::make_shared<std::string const>(path)});
}
Json::Value reply = Json::arrayValue;

View File

@ -29,7 +29,6 @@
using namespace solidity::langutil;
using namespace solidity::lsp;
using namespace solidity::util;
using namespace std;
Json::Value HandlerBase::toRange(SourceLocation const& _location) const
{
@ -52,10 +51,10 @@ Json::Value HandlerBase::toJson(SourceLocation const& _location) const
return item;
}
pair<string, LineColumn> HandlerBase::extractSourceUnitNameAndLineColumn(Json::Value const& _args) const
std::pair<std::string, LineColumn> HandlerBase::extractSourceUnitNameAndLineColumn(Json::Value const& _args) const
{
string const uri = _args["textDocument"]["uri"].asString();
string const sourceUnitName = fileRepository().uriToSourceUnitName(uri);
std::string const uri = _args["textDocument"]["uri"].asString();
std::string const sourceUnitName = fileRepository().uriToSourceUnitName(uri);
if (!fileRepository().sourceUnits().count(sourceUnitName))
BOOST_THROW_EXCEPTION(
RequestError(ErrorCode::RequestFailed) <<

View File

@ -46,7 +46,6 @@
#include <fmt/format.h>
using namespace std;
using namespace std::string_literals;
using namespace std::placeholders;
@ -109,7 +108,7 @@ Json::Value semanticTokensLegend()
tokenTypes.append("operator");
tokenTypes.append("parameter");
tokenTypes.append("property");
tokenTypes.append("string");
tokenTypes.append("std::string");
tokenTypes.append("struct");
tokenTypes.append("type");
tokenTypes.append("typeParameter");
@ -137,19 +136,19 @@ LanguageServer::LanguageServer(Transport& _transport):
{"$/cancelRequest", [](auto, auto) {/*nothing for now as we are synchronous */}},
{"cancelRequest", [](auto, auto) {/*nothing for now as we are synchronous */}},
{"exit", [this](auto, auto) { m_state = (m_state == State::ShutdownRequested ? State::ExitRequested : State::ExitWithoutShutdown); }},
{"initialize", bind(&LanguageServer::handleInitialize, this, _1, _2)},
{"initialized", bind(&LanguageServer::handleInitialized, this, _1, _2)},
{"initialize", std::bind(&LanguageServer::handleInitialize, this, _1, _2)},
{"initialized", std::bind(&LanguageServer::handleInitialized, this, _1, _2)},
{"$/setTrace", [this](auto, Json::Value const& args) { setTrace(args["value"]); }},
{"shutdown", [this](auto, auto) { m_state = State::ShutdownRequested; }},
{"textDocument/definition", GotoDefinition(*this) },
{"textDocument/didOpen", bind(&LanguageServer::handleTextDocumentDidOpen, this, _2)},
{"textDocument/didChange", bind(&LanguageServer::handleTextDocumentDidChange, this, _2)},
{"textDocument/didClose", bind(&LanguageServer::handleTextDocumentDidClose, this, _2)},
{"textDocument/didOpen", std::bind(&LanguageServer::handleTextDocumentDidOpen, this, _2)},
{"textDocument/didChange", std::bind(&LanguageServer::handleTextDocumentDidChange, this, _2)},
{"textDocument/didClose", std::bind(&LanguageServer::handleTextDocumentDidClose, this, _2)},
{"textDocument/hover", DocumentHoverHandler(*this) },
{"textDocument/rename", RenameSymbol(*this) },
{"textDocument/implementation", GotoDefinition(*this) },
{"textDocument/semanticTokens/full", bind(&LanguageServer::semanticTokensFull, this, _1, _2)},
{"workspace/didChangeConfiguration", bind(&LanguageServer::handleWorkspaceDidChangeConfiguration, this, _2)},
{"textDocument/semanticTokens/full", std::bind(&LanguageServer::semanticTokensFull, this, _1, _2)},
{"workspace/didChangeConfiguration", std::bind(&LanguageServer::handleWorkspaceDidChangeConfiguration, this, _2)},
},
m_fileRepository("/" /* basePath */, {} /* no search paths */),
m_compilerStack{m_fileRepository.reader()}
@ -196,7 +195,7 @@ void LanguageServer::changeConfiguration(Json::Value const& _settings)
int typeFailureCount = 0;
if (jsonIncludePaths.isArray())
{
vector<boost::filesystem::path> includePaths;
std::vector<boost::filesystem::path> includePaths;
for (Json::Value const& jsonPath: jsonIncludePaths)
{
if (jsonPath.isString())
@ -214,9 +213,9 @@ void LanguageServer::changeConfiguration(Json::Value const& _settings)
}
}
vector<boost::filesystem::path> LanguageServer::allSolidityFilesFromProject() const
std::vector<boost::filesystem::path> LanguageServer::allSolidityFilesFromProject() const
{
vector<fs::path> collectedPaths{};
std::vector<fs::path> collectedPaths{};
// We explicitly decided against including all files from include paths but leave the possibility
// open for a future PR to enable such a feature to be optionally enabled (default disabled).
@ -242,7 +241,7 @@ void LanguageServer::compile()
// so we just remove all non-open files.
FileRepository oldRepository(m_fileRepository.basePath(), m_fileRepository.includePaths());
swap(oldRepository, m_fileRepository);
std::swap(oldRepository, m_fileRepository);
// Load all solidity files from project.
if (m_fileLoadStrategy == FileLoadStrategy::ProjectDirectory)
@ -256,7 +255,7 @@ void LanguageServer::compile()
}
// Overwrite all files as opened by the client, including the ones which might potentially have changes.
for (string const& fileName: m_openFiles)
for (std::string const& fileName: m_openFiles)
m_fileRepository.setSourceByUri(
fileName,
oldRepository.sourceUnits().at(oldRepository.uriToSourceUnitName(fileName))
@ -266,7 +265,7 @@ void LanguageServer::compile()
m_compilerStack.reset(false);
m_compilerStack.setSources(m_fileRepository.sourceUnits());
m_compilerStack.compile(CompilerStack::State::AnalysisPerformed);
m_compilerStack.compile(CompilerStack::State::AnalysisSuccessful);
}
void LanguageServer::compileAndUpdateDiagnostics()
@ -275,13 +274,13 @@ void LanguageServer::compileAndUpdateDiagnostics()
// These are the source units we will sent diagnostics to the client for sure,
// even if it is just to clear previous diagnostics.
map<string, Json::Value> diagnosticsBySourceUnit;
for (string const& sourceUnitName: m_fileRepository.sourceUnits() | ranges::views::keys)
std::map<std::string, Json::Value> diagnosticsBySourceUnit;
for (std::string const& sourceUnitName: m_fileRepository.sourceUnits() | ranges::views::keys)
diagnosticsBySourceUnit[sourceUnitName] = Json::arrayValue;
for (string const& sourceUnitName: m_nonemptyDiagnostics)
for (std::string const& sourceUnitName: m_nonemptyDiagnostics)
diagnosticsBySourceUnit[sourceUnitName] = Json::arrayValue;
for (shared_ptr<Error const> const& error: m_compilerStack.errors())
for (std::shared_ptr<Error const> const& error: m_compilerStack.errors())
{
SourceLocation const* location = error->sourceLocation();
if (!location || !location->sourceName)
@ -292,8 +291,8 @@ void LanguageServer::compileAndUpdateDiagnostics()
jsonDiag["source"] = "solc";
jsonDiag["severity"] = toDiagnosticSeverity(error->type());
jsonDiag["code"] = Json::UInt64{error->errorId().error};
string message = Error::formatErrorType(error->type()) + ":";
if (string const* comment = error->comment())
std::string message = Error::formatErrorType(error->type()) + ":";
if (std::string const* comment = error->comment())
message += " " + *comment;
jsonDiag["message"] = std::move(message);
jsonDiag["range"] = toRange(*location);
@ -314,7 +313,7 @@ void LanguageServer::compileAndUpdateDiagnostics()
{
Json::Value extra;
extra["openFileCount"] = Json::UInt64(diagnosticsBySourceUnit.size());
m_client.trace("Number of currently open files: " + to_string(diagnosticsBySourceUnit.size()), extra);
m_client.trace("Number of currently open files: " + std::to_string(diagnosticsBySourceUnit.size()), extra);
}
m_nonemptyDiagnostics.clear();
@ -336,13 +335,13 @@ bool LanguageServer::run()
MessageID id;
try
{
optional<Json::Value> const jsonMessage = m_client.receive();
std::optional<Json::Value> const jsonMessage = m_client.receive();
if (!jsonMessage)
continue;
if ((*jsonMessage)["method"].isString())
{
string const methodName = (*jsonMessage)["method"].asString();
std::string const methodName = (*jsonMessage)["method"].asString();
id = (*jsonMessage)["id"];
lspDebug(fmt::format("received method call: {}", methodName));
@ -391,7 +390,7 @@ void LanguageServer::handleInitialize(MessageID _id, Json::Value const& _args)
// The default of FileReader is to use `.`, but the path from where the LSP was started
// should not matter.
string rootPath("/");
std::string rootPath("/");
if (Json::Value uri = _args["rootUri"])
{
rootPath = uri.asString();
@ -414,7 +413,7 @@ void LanguageServer::handleInitialize(MessageID _id, Json::Value const& _args)
Json::Value replyArgs;
replyArgs["serverInfo"]["name"] = "solc";
replyArgs["serverInfo"]["version"] = string(VersionNumber);
replyArgs["serverInfo"]["version"] = std::string(VersionNumber);
replyArgs["capabilities"]["definitionProvider"] = true;
replyArgs["capabilities"]["implementationProvider"] = true;
replyArgs["capabilities"]["textDocumentSync"]["change"] = 2; // 0=none, 1=full, 2=incremental
@ -440,7 +439,7 @@ void LanguageServer::semanticTokensFull(MessageID _id, Json::Value const& _args)
compile();
auto const sourceName = m_fileRepository.uriToSourceUnitName(uri.as<string>());
auto const sourceName = m_fileRepository.uriToSourceUnitName(uri.as<std::string>());
SourceUnit const& ast = m_compilerStack.ast(sourceName);
m_compilerStack.charStream(sourceName);
Json::Value data = SemanticTokensBuilder().build(ast, m_compilerStack.charStream(sourceName));
@ -465,7 +464,7 @@ void LanguageServer::setTrace(Json::Value const& _args)
// Simply ignore invalid parameter.
return;
string const stringValue = _args.asString();
std::string const stringValue = _args.asString();
if (stringValue == "off")
m_client.setTrace(TraceValue::Off);
else if (stringValue == "messages")
@ -484,8 +483,8 @@ void LanguageServer::handleTextDocumentDidOpen(Json::Value const& _args)
"Text document parameter missing."
);
string text = _args["textDocument"]["text"].asString();
string uri = _args["textDocument"]["uri"].asString();
std::string text = _args["textDocument"]["text"].asString();
std::string uri = _args["textDocument"]["uri"].asString();
m_openFiles.insert(uri);
m_fileRepository.setSourceByUri(uri, std::move(text));
compileAndUpdateDiagnostics();
@ -495,7 +494,7 @@ void LanguageServer::handleTextDocumentDidChange(Json::Value const& _args)
{
requireServerInitialized();
string const uri = _args["textDocument"]["uri"].asString();
std::string const uri = _args["textDocument"]["uri"].asString();
for (Json::Value jsonContentChange: _args["contentChanges"])
{
@ -505,24 +504,24 @@ void LanguageServer::handleTextDocumentDidChange(Json::Value const& _args)
"Invalid content reference."
);
string const sourceUnitName = m_fileRepository.uriToSourceUnitName(uri);
std::string const sourceUnitName = m_fileRepository.uriToSourceUnitName(uri);
lspRequire(
m_fileRepository.sourceUnits().count(sourceUnitName),
ErrorCode::RequestFailed,
"Unknown file: " + uri
);
string text = jsonContentChange["text"].asString();
std::string text = jsonContentChange["text"].asString();
if (jsonContentChange["range"].isObject()) // otherwise full content update
{
optional<SourceLocation> change = parseRange(m_fileRepository, sourceUnitName, jsonContentChange["range"]);
std::optional<SourceLocation> change = parseRange(m_fileRepository, sourceUnitName, jsonContentChange["range"]);
lspRequire(
change && change->hasText(),
ErrorCode::RequestFailed,
"Invalid source range: " + util::jsonCompactPrint(jsonContentChange["range"])
);
string buffer = m_fileRepository.sourceUnits().at(sourceUnitName);
std::string buffer = m_fileRepository.sourceUnits().at(sourceUnitName);
buffer.replace(static_cast<size_t>(change->start), static_cast<size_t>(change->end - change->start), std::move(text));
text = std::move(buffer);
}
@ -542,7 +541,7 @@ void LanguageServer::handleTextDocumentDidClose(Json::Value const& _args)
"Text document parameter missing."
);
string uri = _args["textDocument"]["uri"].asString();
std::string uri = _args["textDocument"]["uri"].asString();
m_openFiles.erase(uri);
compileAndUpdateDiagnostics();
@ -550,17 +549,17 @@ void LanguageServer::handleTextDocumentDidClose(Json::Value const& _args)
ASTNode const* LanguageServer::astNodeAtSourceLocation(std::string const& _sourceUnitName, LineColumn const& _filePos)
{
return get<ASTNode const*>(astNodeAndOffsetAtSourceLocation(_sourceUnitName, _filePos));
return std::get<ASTNode const*>(astNodeAndOffsetAtSourceLocation(_sourceUnitName, _filePos));
}
tuple<ASTNode const*, int> LanguageServer::astNodeAndOffsetAtSourceLocation(std::string const& _sourceUnitName, LineColumn const& _filePos)
std::tuple<ASTNode const*, int> LanguageServer::astNodeAndOffsetAtSourceLocation(std::string const& _sourceUnitName, LineColumn const& _filePos)
{
if (m_compilerStack.state() < CompilerStack::AnalysisPerformed)
if (m_compilerStack.state() < CompilerStack::AnalysisSuccessful)
return {nullptr, -1};
if (!m_fileRepository.sourceUnits().count(_sourceUnitName))
return {nullptr, -1};
optional<int> sourcePos = m_compilerStack.charStream(_sourceUnitName).translateLineColumnToPosition(_filePos);
std::optional<int> sourcePos = m_compilerStack.charStream(_sourceUnitName).translateLineColumnToPosition(_filePos);
if (!sourcePos)
return {nullptr, -1};

View File

@ -29,7 +29,6 @@
using namespace solidity::frontend;
using namespace solidity::langutil;
using namespace solidity::lsp;
using namespace std;
namespace
{
@ -51,8 +50,8 @@ CallableDeclaration const* extractCallableDeclaration(FunctionCall const& _funct
void RenameSymbol::operator()(MessageID _id, Json::Value const& _args)
{
auto const&& [sourceUnitName, lineColumn] = extractSourceUnitNameAndLineColumn(_args);
string const newName = _args["newName"].asString();
string const uri = _args["textDocument"]["uri"].asString();
std::string const newName = _args["newName"].asString();
std::string const uri = _args["textDocument"]["uri"].asString();
ASTNode const* sourceNode = m_server.astNodeAtSourceLocation(sourceUnitName, lineColumn);
@ -61,7 +60,7 @@ void RenameSymbol::operator()(MessageID _id, Json::Value const& _args)
m_sourceUnits = { &m_server.compilerStack().ast(sourceUnitName) };
m_locations.clear();
optional<int> cursorBytePosition = charStreamProvider()
std::optional<int> cursorBytePosition = charStreamProvider()
.charStream(sourceUnitName)
.translateLineColumnToPosition(lineColumn);
solAssert(cursorBytePosition.has_value(), "Expected source pos");
@ -72,7 +71,7 @@ void RenameSymbol::operator()(MessageID _id, Json::Value const& _args)
for (auto const& [name, content]: fileRepository().sourceUnits())
{
auto const& sourceUnit = m_server.compilerStack().ast(name);
for (auto const* referencedSourceUnit: sourceUnit.referencedSourceUnits(true, util::convertContainer<set<SourceUnit const*>>(m_sourceUnits)))
for (auto const* referencedSourceUnit: sourceUnit.referencedSourceUnits(true, util::convertContainer<std::set<SourceUnit const*>>(m_sourceUnits)))
if (*referencedSourceUnit->location().sourceName == sourceUnitName)
{
m_sourceUnits.insert(&sourceUnit);
@ -101,8 +100,8 @@ void RenameSymbol::operator()(MessageID _id, Json::Value const& _args)
solAssert(i->isValid());
// Replace in our file repository
string const uri = fileRepository().sourceUnitNameToUri(*i->sourceName);
string buffer = fileRepository().sourceUnits().at(*i->sourceName);
std::string const uri = fileRepository().sourceUnitNameToUri(*i->sourceName);
std::string buffer = fileRepository().sourceUnits().at(*i->sourceName);
buffer.replace((size_t)i->start, (size_t)(i->end - i->start), newName);
fileRepository().setSourceByUri(uri, std::move(buffer));
@ -155,7 +154,7 @@ void RenameSymbol::extractNameAndDeclaration(ASTNode const& _node, int _cursorBy
else if (auto const* inlineAssembly = dynamic_cast<InlineAssembly const*>(&_node))
extractNameAndDeclaration(*inlineAssembly, _cursorBytePosition);
else
solAssert(false, "Unexpected ASTNODE id: " + to_string(_node.id()));
solAssert(false, "Unexpected ASTNODE id: " + std::to_string(_node.id()));
lspDebug(fmt::format("Goal: rename '{}', loc: {}-{}", m_symbolName, m_declarationToRename->nameLocation().start, m_declarationToRename->nameLocation().end));
}
@ -297,7 +296,7 @@ void RenameSymbol::Visitor::endVisit(InlineAssembly const& _node)
{
for (auto&& [identifier, externalReference]: _node.annotation().externalReferences)
{
string identifierName = identifier->name.str();
std::string identifierName = identifier->name.str();
if (!externalReference.suffix.empty())
identifierName = identifierName.substr(0, identifierName.length() - externalReference.suffix.size() - 1);

View File

@ -23,7 +23,6 @@
#include <fmt/format.h>
using namespace std;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -33,10 +32,10 @@ namespace solidity::lsp
namespace
{
optional<SemanticTokenType> semanticTokenTypeForType(frontend::Type const* _type)
std::optional<SemanticTokenType> semanticTokenTypeForType(frontend::Type const* _type)
{
if (!_type)
return nullopt;
return std::nullopt;
switch (_type->category())
{
@ -119,7 +118,7 @@ void SemanticTokensBuilder::encode(
auto const [line, startChar] = m_charStream->translatePositionToLineColumn(_sourceLocation.start);
auto const length = _sourceLocation.end - _sourceLocation.start;
lspDebug(fmt::format("encode [{}:{}..{}] {}", line, startChar, length, _tokenType));
lspDebug(fmt::format("encode [{}:{}..{}] {}", line, startChar, length, static_cast<int>(_tokenType)));
m_encodedTokens.append(line - m_lastLine);
if (line == m_lastLine)

View File

@ -37,34 +37,33 @@
#include <fcntl.h>
#endif
using namespace std;
using namespace solidity::lsp;
// {{{ Transport
optional<Json::Value> Transport::receive()
std::optional<Json::Value> Transport::receive()
{
auto const headers = parseHeaders();
if (!headers)
{
error({}, ErrorCode::ParseError, "Could not parse RPC headers.");
return nullopt;
return std::nullopt;
}
if (!headers->count("content-length"))
{
error({}, ErrorCode::ParseError, "No content-length header found.");
return nullopt;
return std::nullopt;
}
string const data = readBytes(stoul(headers->at("content-length")));
std::string const data = readBytes(stoul(headers->at("content-length")));
Json::Value jsonMessage;
string jsonParsingErrors;
std::string jsonParsingErrors;
solidity::util::jsonParseStrict(data, jsonMessage, &jsonParsingErrors);
if (!jsonParsingErrors.empty() || !jsonMessage || !jsonMessage.isObject())
{
error({}, ErrorCode::ParseError, "Could not parse RPC JSON payload. " + jsonParsingErrors);
return nullopt;
return std::nullopt;
}
return {std::move(jsonMessage)};
@ -82,9 +81,9 @@ void Transport::trace(std::string _message, Json::Value _extra)
}
}
optional<map<string, string>> Transport::parseHeaders()
std::optional<std::map<std::string, std::string>> Transport::parseHeaders()
{
map<string, string> headers;
std::map<std::string, std::string> headers;
while (true)
{
@ -93,18 +92,18 @@ optional<map<string, string>> Transport::parseHeaders()
break;
auto const delimiterPos = line.find(':');
if (delimiterPos == string::npos)
return nullopt;
if (delimiterPos == std::string::npos)
return std::nullopt;
auto const name = boost::to_lower_copy(line.substr(0, delimiterPos));
auto const value = line.substr(delimiterPos + 1);
if (!headers.emplace(boost::trim_copy(name), boost::trim_copy(value)).second)
return nullopt;
return std::nullopt;
}
return {std::move(headers)};
}
void Transport::notify(string _method, Json::Value _message)
void Transport::notify(std::string _method, Json::Value _message)
{
Json::Value json;
json["method"] = std::move(_method);
@ -119,7 +118,7 @@ void Transport::reply(MessageID _id, Json::Value _message)
send(std::move(json), _id);
}
void Transport::error(MessageID _id, ErrorCode _code, string _message)
void Transport::error(MessageID _id, ErrorCode _code, std::string _message)
{
Json::Value json;
json["error"]["code"] = static_cast<int>(_code);
@ -135,7 +134,7 @@ void Transport::send(Json::Value _json, MessageID _id)
_json["id"] = _id;
// Trailing CRLF only for easier readability.
string const jsonString = solidity::util::jsonCompactPrint(_json);
std::string const jsonString = solidity::util::jsonCompactPrint(_json);
writeBytes(fmt::format("Content-Length: {}\r\n\r\n", jsonString.size()));
writeBytes(jsonString);
@ -144,7 +143,7 @@ void Transport::send(Json::Value _json, MessageID _id)
// }}}
// {{{ IOStreamTransport
IOStreamTransport::IOStreamTransport(istream& _in, ostream& _out):
IOStreamTransport::IOStreamTransport(std::istream& _in, std::ostream& _out):
m_input{_in},
m_output{_out}
{
@ -162,7 +161,7 @@ std::string IOStreamTransport::readBytes(size_t _length)
std::string IOStreamTransport::getline()
{
string line;
std::string line;
std::getline(m_input, line);
return line;
}

View File

@ -30,21 +30,20 @@ namespace solidity::lsp
using namespace frontend;
using namespace langutil;
using namespace std;
optional<LineColumn> parseLineColumn(Json::Value const& _lineColumn)
std::optional<LineColumn> parseLineColumn(Json::Value const& _lineColumn)
{
if (_lineColumn.isObject() && _lineColumn["line"].isInt() && _lineColumn["character"].isInt())
return LineColumn{_lineColumn["line"].asInt(), _lineColumn["character"].asInt()};
else
return nullopt;
return std::nullopt;
}
Json::Value toJson(LineColumn const& _pos)
{
Json::Value json = Json::objectValue;
json["line"] = max(_pos.line, 0);
json["character"] = max(_pos.column, 0);
json["line"] = std::max(_pos.line, 0);
json["character"] = std::max(_pos.column, 0);
return json;
}
@ -70,10 +69,10 @@ Declaration const* referencedDeclaration(Expression const* _expression)
return nullptr;
}
optional<SourceLocation> declarationLocation(Declaration const* _declaration)
std::optional<SourceLocation> declarationLocation(Declaration const* _declaration)
{
if (!_declaration)
return nullopt;
return std::nullopt;
if (_declaration->nameLocation().isValid())
return _declaration->nameLocation();
@ -81,43 +80,43 @@ optional<SourceLocation> declarationLocation(Declaration const* _declaration)
if (_declaration->location().isValid())
return _declaration->location();
return nullopt;
return std::nullopt;
}
optional<SourceLocation> parsePosition(
std::optional<SourceLocation> parsePosition(
FileRepository const& _fileRepository,
string const& _sourceUnitName,
std::string const& _sourceUnitName,
Json::Value const& _position
)
{
if (!_fileRepository.sourceUnits().count(_sourceUnitName))
return nullopt;
return std::nullopt;
if (optional<LineColumn> lineColumn = parseLineColumn(_position))
if (optional<int> const offset = CharStream::translateLineColumnToPosition(
if (std::optional<LineColumn> lineColumn = parseLineColumn(_position))
if (std::optional<int> const offset = CharStream::translateLineColumnToPosition(
_fileRepository.sourceUnits().at(_sourceUnitName),
*lineColumn
))
return SourceLocation{*offset, *offset, make_shared<string>(_sourceUnitName)};
return nullopt;
return SourceLocation{*offset, *offset, std::make_shared<std::string>(_sourceUnitName)};
return std::nullopt;
}
optional<SourceLocation> parseRange(FileRepository const& _fileRepository, string const& _sourceUnitName, Json::Value const& _range)
std::optional<SourceLocation> parseRange(FileRepository const& _fileRepository, std::string const& _sourceUnitName, Json::Value const& _range)
{
if (!_range.isObject())
return nullopt;
optional<SourceLocation> start = parsePosition(_fileRepository, _sourceUnitName, _range["start"]);
optional<SourceLocation> end = parsePosition(_fileRepository, _sourceUnitName, _range["end"]);
return std::nullopt;
std::optional<SourceLocation> start = parsePosition(_fileRepository, _sourceUnitName, _range["start"]);
std::optional<SourceLocation> end = parsePosition(_fileRepository, _sourceUnitName, _range["end"]);
if (!start || !end)
return nullopt;
return std::nullopt;
solAssert(*start->sourceName == *end->sourceName);
start->end = end->end;
return start;
}
string stripFileUriSchemePrefix(string const& _path)
std::string stripFileUriSchemePrefix(std::string const& _path)
{
regex const windowsDriveLetterPath("^file:///[a-zA-Z]:/");
std::regex const windowsDriveLetterPath("^file:///[a-zA-Z]:/");
if (regex_search(_path, windowsDriveLetterPath))
return _path.substr(8);
if (_path.find("file://") == 0)

View File

@ -28,7 +28,6 @@
#include <range/v3/algorithm/find_if_not.hpp>
#include <range/v3/view/subrange.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::frontend;
@ -36,17 +35,17 @@ using namespace solidity::frontend;
namespace
{
string::const_iterator skipLineOrEOS(
string::const_iterator _nlPos,
string::const_iterator _end
std::string::const_iterator skipLineOrEOS(
std::string::const_iterator _nlPos,
std::string::const_iterator _end
)
{
return (_nlPos == _end) ? _end : ++_nlPos;
}
string::const_iterator firstNonIdentifier(
string::const_iterator _pos,
string::const_iterator _end
std::string::const_iterator firstNonIdentifier(
std::string::const_iterator _pos,
std::string::const_iterator _end
)
{
auto currPos = _pos;
@ -58,18 +57,18 @@ string::const_iterator firstNonIdentifier(
return currPos;
}
string::const_iterator firstWhitespaceOrNewline(
string::const_iterator _pos,
string::const_iterator _end
std::string::const_iterator firstWhitespaceOrNewline(
std::string::const_iterator _pos,
std::string::const_iterator _end
)
{
return ranges::find_first_of(ranges::make_subrange(_pos, _end), " \t\n");
}
string::const_iterator skipWhitespace(
string::const_iterator _pos,
string::const_iterator _end
std::string::const_iterator skipWhitespace(
std::string::const_iterator _pos,
std::string::const_iterator _end
)
{
auto isWhitespace = [](char const& c) { return (c == ' ' || c == '\t'); };
@ -78,7 +77,7 @@ string::const_iterator skipWhitespace(
}
multimap<string, DocTag> DocStringParser::parse()
std::multimap<std::string, DocTag> DocStringParser::parse()
{
m_lastTag = nullptr;
m_docTags = {};
@ -96,7 +95,7 @@ multimap<string, DocTag> DocStringParser::parse()
{
// we found a tag
iter tagNameEndPos = firstWhitespaceOrNewline(tagPos, end);
string tagName{tagPos + 1, tagNameEndPos};
std::string tagName{tagPos + 1, tagNameEndPos};
iter tagDataPos = (tagNameEndPos != end) ? tagNameEndPos + 1 : tagNameEndPos;
currPos = parseDocTag(tagDataPos, end, tagName);
}
@ -141,7 +140,7 @@ DocStringParser::iter DocStringParser::parseDocTagParam(iter _pos, iter _end)
return _end;
}
auto nameEndPos = firstNonIdentifier(nameStartPos, _end);
auto paramName = string(nameStartPos, nameEndPos);
auto paramName = std::string(nameStartPos, nameEndPos);
auto descStartPos = skipWhitespace(nameEndPos, _end);
auto nlPos = find(descStartPos, _end, '\n');
@ -152,7 +151,7 @@ DocStringParser::iter DocStringParser::parseDocTagParam(iter _pos, iter _end)
return _end;
}
auto paramDesc = string(descStartPos, nlPos);
auto paramDesc = std::string(descStartPos, nlPos);
newTag("param");
m_lastTag->paramName = paramName;
m_lastTag->content = paramDesc;
@ -160,7 +159,7 @@ DocStringParser::iter DocStringParser::parseDocTagParam(iter _pos, iter _end)
return skipLineOrEOS(nlPos, _end);
}
DocStringParser::iter DocStringParser::parseDocTag(iter _pos, iter _end, string const& _tag)
DocStringParser::iter DocStringParser::parseDocTag(iter _pos, iter _end, std::string const& _tag)
{
// TODO: need to check for @(start of a tag) between here and the end of line
// for all cases.
@ -178,7 +177,7 @@ DocStringParser::iter DocStringParser::parseDocTag(iter _pos, iter _end, string
return parseDocTagLine(_pos, _end, true);
}
void DocStringParser::newTag(string const& _tagName)
void DocStringParser::newTag(std::string const& _tagName)
{
m_lastTag = &m_docTags.insert(make_pair(_tagName, DocTag()))->second;
}

Some files were not shown because too many files have changed in this diff Show More