diff --git a/.circleci/parallel_cli_tests.py b/.circleci/parallel_cli_tests.py index ef789218063a..45cc83aec318 100755 --- a/.circleci/parallel_cli_tests.py +++ b/.circleci/parallel_cli_tests.py @@ -8,6 +8,7 @@ # TODO: We should switch to time-based splitting but that requires JUnit XML report support in cmdlineTests.sh. tests_to_run_in_parallel = [ '~ast_import_export', # ~7 min + '~evmasm_import_export', # ~5 min '~ast_export_with_stop_after_parsing', # ~4 min '~soljson_via_fuzzer', # ~3 min '~via_ir_equivalence', # ~1 min diff --git a/.circleci/soltest.sh b/.circleci/soltest.sh index e350aa23d710..488201bae3ff 100755 --- a/.circleci/soltest.sh +++ b/.circleci/soltest.sh @@ -36,6 +36,7 @@ set -e OPTIMIZE=${OPTIMIZE:-"0"} EVM=${EVM:-"invalid"} +CPUs=${CPUs:-3} REPODIR="$(realpath "$(dirname "$0")/..")" IFS=" " read -r -a BOOST_TEST_ARGS <<< "$BOOST_TEST_ARGS" @@ -67,7 +68,6 @@ get_logfile_basename() { # long-running test cases are next to each other. CIRCLE_NODE_INDEX=$(((CIRCLE_NODE_INDEX + 23 * INDEX_SHIFT) % CIRCLE_NODE_TOTAL)) -CPUs=3 PIDs=() for run in $(seq 0 $((CPUs - 1))) do diff --git a/CMakeLists.txt b/CMakeLists.txt index 6583f7cd4742..73e7930b7222 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.13.0) -set(ETH_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake" CACHE PATH "The the path to the cmake directory") +set(ETH_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake" CACHE PATH "The path to the cmake directory") list(APPEND CMAKE_MODULE_PATH ${ETH_CMAKE_DIR}) # Set the build type, if none was specified. @@ -21,7 +21,7 @@ include(EthPolicy) eth_policy() # project name and version should be set after cmake_policy CMP0048 -set(PROJECT_VERSION "0.8.21") +set(PROJECT_VERSION "0.8.22") # OSX target needed in order to support std::visit set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14") project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX) diff --git a/Changelog.md b/Changelog.md index 78e1569d0195..866e996ee82d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,30 @@ +### 0.8.22 (2023-10-25) + +Language Features: + * Allow defining events at file level. + + +Compiler Features: + * Code Generator: Remove redundant overflow checks of certain ``for`` loops when the counter variable cannot overflow. + * Commandline Interface: Add ``--no-import-callback`` option that prevents the compiler from loading source files not given explicitly on the CLI or in Standard JSON input. + * Commandline Interface: Add an experimental ``--import-asm-json`` option that can import EVM assembly in the format used by ``--asm-json``. + * Commandline Interface: Use proper severity and coloring also for error messages produced outside of the compilation pipeline. + * EVM: Deprecate support for "homestead", "tangerineWhistle", "spuriousDragon" and "byzantium" EVM versions. + * Parser: Remove the experimental error recovery mode (``--error-recovery`` / ``settings.parserErrorRecovery``). + * SMTChecker: Support user-defined operators. + * 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: + * AST: Fix wrong initial ID for Yul nodes in the AST. + * Code Generator: Fix output from via-IR code generator being dependent on which files were discovered by import callback. In some cases, a different AST ID assignment would alter the order of functions in internal dispatch, resulting in superficially different but semantically equivalent bytecode. + * NatSpec: Fix internal error when requesting userdoc or devdoc for a contract that emits an event defined in a foreign contract or interface. + * SMTChecker: Fix encoding error that causes loops to unroll after completion. + * SMTChecker: Fix inconsistency on constant condition checks when ``while`` or ``for`` loops are unrolled before the condition check. + * Yul Optimizer: Fix replacement decisions during CSE being affected by Yul variable names generated by the compiler, resulting in different (but equivalent) bytecode in some situations. + + ### 0.8.21 (2023-07-19) Important Bugfixes: diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index 8892566820cd..db07fb888555 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -3,9 +3,9 @@ ### Requirements - [ ] GitHub account with access to [solidity](https://github.com/ethereum/solidity), [solc-js](https://github.com/ethereum/solc-js), [solc-bin](https://github.com/ethereum/solc-bin), [homebrew-ethereum](https://github.com/ethereum/homebrew-ethereum), - [solidity-blog](https://github.com/ethereum/solidity-blog) and [solidity-portal](https://github.com/ethereum/solidity-portal) repositories. + [solidity-website](https://github.com/ethereum/solidity-website). - [ ] DockerHub account with push rights to the [``solc`` image](https://hub.docker.com/r/ethereum/solc). - - [ ] Lauchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and + - [ ] Launchpad (Ubuntu One) account with a membership in the ["Ethereum" team](https://launchpad.net/~ethereum) and a gnupg key for your email in the ``ethereum.org`` domain (has to be version 1, gpg2 won't work). - [ ] Ubuntu/Debian dependencies of the PPA scripts: ``devscripts``, ``debhelper``, ``dput``, ``git``, ``wget``, ``ca-certificates``. - [ ] [npm Registry](https://www.npmjs.com) account added as a collaborator for the [``solc`` package](https://www.npmjs.com/package/solc). @@ -37,8 +37,8 @@ At least a day before the release: - [ ] Prepare drafts of Twitter, Reddit and Solidity Forum announcements. ### Blog Post - - [ ] Create a post on [solidity-blog](https://github.com/ethereum/solidity-blog) in the ``Releases`` category and explain some of the new features or concepts. - - [ ] Create a post on [solidity-blog](https://github.com/ethereum/solidity-blog) in the ``Security Alerts`` category in case of important bug(s). + - [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Releases`` category and explain some of the new features or concepts. + - [ ] Create a post on [solidity-website](https://github.com/ethereum/solidity-website/tree/main/src/posts) in the ``Security Alerts`` category in case of important bug(s). ### Changelog - [ ] Sort the changelog entries alphabetically and correct any errors you notice. Commit it. @@ -104,9 +104,9 @@ At least a day before the release: - [ ] Make sure the documentation for the new release has been published successfully. Go to the [documentation status page at ReadTheDocs](https://readthedocs.org/projects/solidity/) and verify that the new version is listed, works and is marked as default. - [ ] Remove "still in progress" warning from the [release notes](https://github.com/ethereum/solidity/releases). - - [ ] Merge the [blog posts](https://github.com/ethereum/solidity-blog/pulls) related to the release. + - [ ] Merge the [blog posts](https://github.com/ethereum/solidity-website/pulls) related to the release. - [ ] Create a commit to increase the version number on ``develop`` in ``CMakeLists.txt`` and add a new skeleton changelog entry. - - [ ] Update the release information section [in the source of soliditylang.org](https://github.com/ethereum/solidity-portal/blob/master/index.html). + - [ ] Update the release information section [in the source of soliditylang.org](https://github.com/ethereum/solidity-website/blob/main/src/pages/index.tsx). - [ ] Announce on [Twitter](https://twitter.com/solidity_lang), including links to the release and the blog post. - [ ] Announce on [Fosstodon](https://fosstodon.org/@solidity/), including links to the release and the blog post. - [ ] Share the announcement on Reddit in [``/r/ethdev``](https://reddit.com/r/ethdev/), cross-posted to [``/r/ethereum``](https://reddit.com/r/ethereum/). diff --git a/cmake/fmtlib.cmake b/cmake/fmtlib.cmake index 792bf3b0279a..032a68cd52a0 100644 --- a/cmake/fmtlib.cmake +++ b/cmake/fmtlib.cmake @@ -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") diff --git a/docs/060-breaking-changes.rst b/docs/060-breaking-changes.rst index 25bc15b875c6..e7c93057f62a 100644 --- a/docs/060-breaking-changes.rst +++ b/docs/060-breaking-changes.rst @@ -112,7 +112,7 @@ New Error Reporter ~~~~~~~~~~~~~~~~~~ A new error reporter was introduced, which aims at producing more accessible error messages on the command-line. -It is enabled by default, but passing ``--old-reporter`` falls back to the the deprecated old error reporter. +It is enabled by default, but passing ``--old-reporter`` falls back to the deprecated old error reporter. Metadata Hash Options ~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css index ed21675dd24d..25ab26544318 100644 --- a/docs/_static/css/custom.css +++ b/docs/_static/css/custom.css @@ -16,6 +16,10 @@ --navHeight: 4.5rem; --sideWidth: 300px; + --maxWidth: 80rem; + --desktopInlinePadding: 2rem; + --mobileInlinePadding: 1rem; + --currentVersionHeight: 45px; text-rendering: geometricPrecision; -webkit-font-smoothing: antialiased; @@ -56,7 +60,6 @@ html, body, .wy-grid-for-nav { background-color: var(--color-f) !important; - position: relative; } body { @@ -67,6 +70,10 @@ a { color: var(--color-c); } +a, section { + scroll-margin-top: calc(var(--navHeight) + 2rem); +} + hr { margin-block: 2rem; border-color: var(--color-d) !important; @@ -327,7 +334,6 @@ ul.current ul, .wy-breadcrumbs-aside a, .wy-breadcrumbs-aside a:visited, -/* .wy-breadcrumbs-aside a:not(:visited), */ a.fa.fa-github, a.fa.fa-github:visited, a.fa.fa-github:not(:visited), @@ -361,10 +367,11 @@ footer .rst-footer-buttons { /* Site wrapper, and two children: header and rest */ .unified-wrapper { - position: fixed; + position: relative; + display: flex; + flex-direction: column; inset: 0; - top: var(--navHeight); - max-width: 80rem; + max-width: var(--maxWidth); margin-inline: auto; } @@ -377,17 +384,16 @@ footer .rst-footer-buttons { display: flex; align-items: center; box-shadow: var(--shadow); - backdrop-filter: blur(3px); } .unified-header .inner-header { display: flex; margin-inline: auto; width: 100%; - max-width: 80rem; + max-width: var(--maxWidth); align-items: center; justify-content: space-between; - padding-inline: 2rem; + padding-inline: var(--desktopInlinePadding); padding-block: 1rem; } @@ -398,6 +404,7 @@ footer .rst-footer-buttons { opacity: 95%; background: var(--color-f); z-index: -1; + backdrop-filter: blur(3px); } .unified-header .home-link { @@ -444,6 +451,7 @@ footer .rst-footer-buttons { font-weight: 400; box-sizing: content-box; border-bottom: 1px solid transparent; + white-space: nowrap; } .unified-header .nav-link.active { @@ -455,34 +463,36 @@ footer .rst-footer-buttons { border-bottom: 1px solid var(--color-c); } -/* Rest: Grid, with two children: side bar, and content */ +/* Rest: Flex-row, with two children: side bar, and content */ .unified-wrapper .wy-grid-for-nav { position: relative !important; - display: grid !important; - grid-template-columns: var(--sideWidth) 1fr; - gap: 1rem; + display: flex; + margin-inline: auto; } /* First child: Side bar */ .unified-wrapper .wy-grid-for-nav nav.wy-nav-side { - position: relative; + position: fixed; display: flex; flex-direction: column; background: var(--color-f); color: var(--color-a); - top: 0; - bottom: 0; - left: 0; padding-bottom: unset !important; - min-height: unset !important; z-index: 10 !important; - max-width: var(--sideWidth) !important; + min-height: unset !important; + width: var(--sideWidth) !important; + top: var(--navHeight); + bottom: 0; + left: auto; + overflow: auto; } .unified-wrapper .wy-grid-for-nav nav.wy-nav-side .wy-side-scroll { - position: relative !important; - width: fit-content !important; + position: static !important; + width: unset !important; + overflow: unset !important; height: unset !important; + padding-bottom: 2rem; } .unified-wrapper .wy-grid-for-nav nav.wy-nav-side .wy-side-scroll .wy-side-nav-search { @@ -516,15 +526,15 @@ footer .rst-footer-buttons { /* Second child: Content */ .unified-wrapper .wy-grid-for-nav .wy-nav-content { - position: relative !important; - overflow-y: scroll !important; width: 100%; - max-width: 100vw !important; - padding-inline: 2rem; + max-width: unset !important; /* override */ + padding-inline: var(--desktopInlinePadding); + margin-inline-start: var(--sideWidth); + margin-top: var(--navHeight); } .unified-wrapper .wy-grid-for-nav .wy-nav-content .rst-content { - max-width: 70ch; + max-width: min(70ch, calc(100vw - 2 * var(--desktopInlinePadding) - var(--sideWidth))); margin-inline: auto; } @@ -565,29 +575,15 @@ footer .rst-footer-buttons { } .unified-header .inner-header { - padding-inline: 1rem; - } - - .unified-wrapper .wy-grid-for-nav { - grid-template-columns: 1fr; + padding-inline: var(--mobileInlinePadding); } .unified-wrapper .wy-grid-for-nav nav.wy-nav-side { - position: absolute; - inset-block: 0; - inset-inline-start: 0; - width: var(--sideWidth); - overflow-y: scroll; transform: translateX(-100%); transition: transform 200ms ease-in-out; } /* Menu open styles */ - .unified-wrapper .wy-grid-for-nav nav.wy-nav-side { - position: absolute; - - } - .unified-wrapper.menu-open nav.wy-nav-side { transform: translateX(0); transition: transform 200ms ease-in-out; @@ -612,6 +608,18 @@ footer .rst-footer-buttons { a.skip-to-content { display: none; } + + .wy-nav-content { + margin-inline-start: 0 !important; + } + + .rst-content { + max-width: 100% !important; + } + + .wy-side-scroll { + padding-bottom: 0 !important; + } } ul.search .context { @@ -658,6 +666,8 @@ ul.search .context { .rst-other-versions { background: var(--white) !important; color: var(--color-a) !important; + max-height: calc(100vh - var(--navHeight) - var(--currentVersionHeight)); + overflow-y: scroll; } .rst-other-versions a { @@ -778,9 +788,8 @@ button.mobile-menu-button { font-family: 'Overpass Mono', monospace; } -.wy-breadcrumbs-aside { - display: block; - padding-top: 0; +.wy-breadcrumbs>li { + padding-top: 8px; } .wy-breadcrumbs-aside a { @@ -801,8 +810,9 @@ a.skip-to-content { padding: 2px 4px; font-size: 14px; margin-inline-end: auto; - margin-inline-start: 2rem; + margin-inline-start: 1.5rem; color: var(--color-a); + white-space: nowrap; } a.skip-to-content:focus { diff --git a/docs/_static/fonts/overpass-bold.otf b/docs/_static/fonts/overpass-bold.otf deleted file mode 100644 index 962a5d7628df..000000000000 Binary files a/docs/_static/fonts/overpass-bold.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass-bold.woff2 b/docs/_static/fonts/overpass-bold.woff2 deleted file mode 100644 index f8133b0e93b1..000000000000 Binary files a/docs/_static/fonts/overpass-bold.woff2 and /dev/null differ diff --git a/docs/_static/fonts/overpass-italic.otf b/docs/_static/fonts/overpass-italic.otf deleted file mode 100644 index 19224a86dc1d..000000000000 Binary files a/docs/_static/fonts/overpass-italic.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass-light.otf b/docs/_static/fonts/overpass-light.otf deleted file mode 100644 index b060651a442a..000000000000 Binary files a/docs/_static/fonts/overpass-light.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass-mono-bold.otf b/docs/_static/fonts/overpass-mono-bold.otf deleted file mode 100644 index f8291d926d98..000000000000 Binary files a/docs/_static/fonts/overpass-mono-bold.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass-mono-bold.woff2 b/docs/_static/fonts/overpass-mono-bold.woff2 deleted file mode 100644 index 280570a46adc..000000000000 Binary files a/docs/_static/fonts/overpass-mono-bold.woff2 and /dev/null differ diff --git a/docs/_static/fonts/overpass-mono-regular.otf b/docs/_static/fonts/overpass-mono-regular.otf deleted file mode 100644 index 80a4b839b76c..000000000000 Binary files a/docs/_static/fonts/overpass-mono-regular.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass-mono-regular.woff2 b/docs/_static/fonts/overpass-mono-regular.woff2 deleted file mode 100644 index 280570a46adc..000000000000 Binary files a/docs/_static/fonts/overpass-mono-regular.woff2 and /dev/null differ diff --git a/docs/_static/fonts/overpass-mono/overpass-mono-bold.otf b/docs/_static/fonts/overpass-mono/overpass-mono-bold.otf deleted file mode 100644 index f8291d926d98..000000000000 Binary files a/docs/_static/fonts/overpass-mono/overpass-mono-bold.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass-mono/overpass-mono-regular.otf b/docs/_static/fonts/overpass-mono/overpass-mono-regular.otf deleted file mode 100644 index 80a4b839b76c..000000000000 Binary files a/docs/_static/fonts/overpass-mono/overpass-mono-regular.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass-regular.otf b/docs/_static/fonts/overpass-regular.otf deleted file mode 100644 index 3a7c095fab33..000000000000 Binary files a/docs/_static/fonts/overpass-regular.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass-regular.woff2 b/docs/_static/fonts/overpass-regular.woff2 deleted file mode 100644 index f8133b0e93b1..000000000000 Binary files a/docs/_static/fonts/overpass-regular.woff2 and /dev/null differ diff --git a/docs/_static/fonts/overpass-semibold.otf b/docs/_static/fonts/overpass-semibold.otf deleted file mode 100644 index 176fb43ce14a..000000000000 Binary files a/docs/_static/fonts/overpass-semibold.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass/overpass-bold.otf b/docs/_static/fonts/overpass/overpass-bold.otf deleted file mode 100644 index 962a5d7628df..000000000000 Binary files a/docs/_static/fonts/overpass/overpass-bold.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass/overpass-italic.otf b/docs/_static/fonts/overpass/overpass-italic.otf deleted file mode 100644 index 19224a86dc1d..000000000000 Binary files a/docs/_static/fonts/overpass/overpass-italic.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass/overpass-light.otf b/docs/_static/fonts/overpass/overpass-light.otf deleted file mode 100644 index b060651a442a..000000000000 Binary files a/docs/_static/fonts/overpass/overpass-light.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass/overpass-regular.otf b/docs/_static/fonts/overpass/overpass-regular.otf deleted file mode 100644 index 3a7c095fab33..000000000000 Binary files a/docs/_static/fonts/overpass/overpass-regular.otf and /dev/null differ diff --git a/docs/_static/fonts/overpass/overpass-semibold.otf b/docs/_static/fonts/overpass/overpass-semibold.otf deleted file mode 100644 index 176fb43ce14a..000000000000 Binary files a/docs/_static/fonts/overpass/overpass-semibold.otf and /dev/null differ diff --git a/docs/_static/js/constants.js b/docs/_static/js/constants.js index abdeb4464fc3..67fa16cdb039 100644 --- a/docs/_static/js/constants.js +++ b/docs/_static/js/constants.js @@ -1,11 +1,18 @@ +// Site URL +const SITE_URL = "https://docs.soliditylang.org" +const { origin, pathname } = location; +const pathSplit = pathname.split("/"); +const rootPath = origin.includes(SITE_URL) && pathSplit.length > 3 ? pathSplit.splice(1, 2).join("/") : '' +const ROOT_URL = `${origin}/${rootPath}`; + // Color mode constants const [DARK, LIGHT] = ["dark", "light"]; -const LIGHT_LOGO_PATH = "_static/img/logo.svg"; -const DARK_LOGO_PATH = "_static/img/logo-dark.svg"; -const SUN_ICON_PATH = "_static/img/sun.svg"; -const MOON_ICON_PATH = "_static/img/moon.svg"; -const LIGHT_HAMBURGER_PATH = "_static/img/hamburger-light.svg"; -const DARK_HAMBURGER_PATH = "_static/img/hamburger-dark.svg"; +const LIGHT_LOGO_PATH = `${ROOT_URL}/_static/img/logo.svg`; +const DARK_LOGO_PATH = `${ROOT_URL}/_static/img/logo-dark.svg`; +const SUN_ICON_PATH = `${ROOT_URL}/_static/img/sun.svg`; +const MOON_ICON_PATH = `${ROOT_URL}/_static/img/moon.svg`; +const LIGHT_HAMBURGER_PATH = `${ROOT_URL}/_static/img/hamburger-light.svg`; +const DARK_HAMBURGER_PATH = `${ROOT_URL}/_static/img/hamburger-dark.svg`; const COLOR_TOGGLE_ICON_CLASS = "color-toggle-icon"; const SOLIDITY_LOGO_CLASS = "solidity-logo"; const LS_COLOR_SCHEME = "color-scheme"; diff --git a/docs/_static/js/initialize.js b/docs/_static/js/initialize.js index c875b37df864..a20d4fce7190 100644 --- a/docs/_static/js/initialize.js +++ b/docs/_static/js/initialize.js @@ -63,7 +63,7 @@ function buildHeader() { const skipToContent = document.createElement("a"); skipToContent.classList.add("skip-to-content"); skipToContent.href = "#content"; - skipToContent.innerText = "{ skip to content }"; + skipToContent.innerText = "{skip to content}"; innerHeader.appendChild(skipToContent); const navBar = document.createElement("nav"); @@ -143,23 +143,20 @@ const updateActiveNavLink = () => { document.addEventListener("locationchange", updateActiveNavLink); -function initialize() { - // Preload fonts - const fonts = [ - "overpass-regular.otf", - "overpass-bold.otf", - "overpass-mono-regular.otf", - "overpass-mono-bold.otf", - ]; - fonts.forEach((filename) => { - const link = document.createElement("link"); - link.rel = "preload"; - link.as = "font"; - link.href = `https://solidity-docs-dev.readthedocs.io/en/latest/_static/fonts/${filename}`; - link.crossOrigin = ""; - document.head.appendChild(link); - }); +function updateGitHubEditPath() { + // Replaces the version number in the GitHub edit path with "develop" + const gitHubEditAnchor = document.querySelector(".wy-breadcrumbs-aside > a"); + const url = new URL(gitHubEditAnchor.href); + const split = url.pathname.split("/"); + const versionIndex = split.indexOf("blob") + 1; + split[versionIndex] = "develop"; + url.pathname = split.join("/"); + gitHubEditAnchor.setAttribute("href", url.toString()); + gitHubEditAnchor.setAttribute("target", "_blank"); + gitHubEditAnchor.setAttribute("rel", "noopener noreferrer"); +} +function initialize() { // Rearrange DOM elements for styling rearrangeDom(); @@ -214,6 +211,9 @@ function initialize() { // Update active nav link updateActiveNavLink(); + + // Update GitHub edit path to direct to `develop` branch + updateGitHubEditPath(); } document.addEventListener("DOMContentLoaded", initialize); diff --git a/docs/brand-guide.rst b/docs/brand-guide.rst index 5601b16a8e39..cf471c5e3c5c 100644 --- a/docs/brand-guide.rst +++ b/docs/brand-guide.rst @@ -67,7 +67,7 @@ When using the Solidity logo, please respect the Solidity logo guidelines. Solidity Logo Guidelines ======================== -.. image:: logo.svg +.. image:: solidity_logo.svg :width: 256 *(Right click on the logo to download it.)* diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index d15c72a65424..982444b10330 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -1863,6 +1863,10 @@ "bugs": [], "released": "2023-07-19" }, + "0.8.22": { + "bugs": [], + "released": "2023-10-25" + }, "0.8.3": { "bugs": [ "FullInlinerNonExpressionSplitArgumentEvaluationOrder", diff --git a/docs/conf.py b/docs/conf.py index 550fbf4b36af..ddc3ee81bbdc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -169,7 +169,7 @@ def setup(sphinx): # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -html_extra_path = ["_static/css", "_static/fonts"] +html_extra_path = ["_static/css"] # List of templates of static files to be included in the HTML output. # Keys represent paths to input files and values are dicts containing: diff --git a/docs/contracts/events.rst b/docs/contracts/events.rst index ca992e6ca25c..8c73c31603ae 100644 --- a/docs/contracts/events.rst +++ b/docs/contracts/events.rst @@ -9,12 +9,13 @@ Events Solidity events give an abstraction on top of the EVM's logging functionality. Applications can subscribe and listen to these events through the RPC interface of an Ethereum client. -Events are inheritable members of contracts. When you call them, they cause the +Events can be defined at file level or as inheritable members of contracts (including interfaces and libraries). +When you call them, they cause the arguments to be stored in the transaction's log - a special data structure -in the blockchain. These logs are associated with the address of the contract, +in the blockchain. These logs are associated with the address of the contract that emitted them, are incorporated into the blockchain, and stay there as long as a block is accessible (forever as of now, but this might -change with Serenity). The Log and its event data is not accessible from within +change in the future). The Log and its event data is not accessible from within contracts (not even from the contract that created them). It is possible to request a Merkle proof for logs, so if diff --git a/docs/contracts/function-modifiers.rst b/docs/contracts/function-modifiers.rst index 0d597c0b65a4..454e12ab65cf 100644 --- a/docs/contracts/function-modifiers.rst +++ b/docs/contracts/function-modifiers.rst @@ -132,7 +132,7 @@ variables are set to their :ref:`default values` just as if the f body. The ``_`` symbol can appear in the modifier multiple times. Each occurrence is replaced with -the function body. +the function body, and the function returns the return value of the final occurrence. Arbitrary expressions are allowed for modifier arguments and in this context, all symbols visible from the function are visible in the modifier. Symbols diff --git a/docs/contracts/inheritance.rst b/docs/contracts/inheritance.rst index 7756ce93d279..c787c5af6a90 100644 --- a/docs/contracts/inheritance.rst +++ b/docs/contracts/inheritance.rst @@ -590,9 +590,11 @@ One area where inheritance linearization is especially important and perhaps not Inheriting Different Kinds of Members of the Same Name ====================================================== -It is an error when any of the following pairs in a contract have the same name due to inheritance: - - a function and a modifier - - a function and an event - - an event and a modifier - -As an exception, a state variable getter can override an external function. +The only situations where, due to inheritance, a contract may contain multiple definitions sharing +the same name are: + +- Overloading of functions. +- Overriding of virtual functions. +- Overriding of external virtual functions by state variable getters. +- Overriding of virtual modifiers. +- Overloading of events. diff --git a/docs/grammar/SolidityParser.g4 b/docs/grammar/SolidityParser.g4 index b8744673d69b..4a756029c2ef 100644 --- a/docs/grammar/SolidityParser.g4 +++ b/docs/grammar/SolidityParser.g4 @@ -22,6 +22,7 @@ sourceUnit: ( | enumDefinition | userDefinedValueTypeDefinition | errorDefinition + | eventDefinition )* EOF; //@doc: inline diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index c46767366b0a..abafd0ad3810 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -323,7 +323,7 @@ The following are dependencies for all builds of Solidity: | `CMake`_ (version 3.21.3+ on | Cross-platform build file generator. | | Windows, 3.13+ otherwise) | | +-----------------------------------+-------------------------------------------------------+ -| `Boost`_ (version 1.77 on | C++ libraries. | +| `Boost`_ (version 1.77+ on | C++ libraries. | | Windows, 1.65+ otherwise) | | +-----------------------------------+-------------------------------------------------------+ | `Git`_ | Command-line tool for retrieving source code. | @@ -410,7 +410,7 @@ You need to install the following dependencies for Windows builds of Solidity: +-----------------------------------+-------------------------------------------------------+ | `Visual Studio 2019`_ (Optional) | C++ compiler and dev environment. | +-----------------------------------+-------------------------------------------------------+ -| `Boost`_ (version 1.77) | C++ libraries. | +| `Boost`_ (version 1.77+) | C++ libraries. | +-----------------------------------+-------------------------------------------------------+ If you already have one IDE and only need the compiler and libraries, diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst index ab37872ffb17..b3e144e94744 100644 --- a/docs/internals/optimizer.rst +++ b/docs/internals/optimizer.rst @@ -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, diff --git a/docs/layout-of-source-files.rst b/docs/layout-of-source-files.rst index a5c7164bcc66..600f2ed0f453 100644 --- a/docs/layout-of-source-files.rst +++ b/docs/layout-of-source-files.rst @@ -40,7 +40,7 @@ The comment is recognized by the compiler anywhere in the file at the file level, but it is recommended to put it at the top of the file. More information about how to use SPDX license identifiers -can be found at the `SPDX website `_. +can be found at the `SPDX website `_. .. index:: ! pragma diff --git a/docs/path-resolution.rst b/docs/path-resolution.rst index 00831e609aa6..666d9b8dc9ca 100644 --- a/docs/path-resolution.rst +++ b/docs/path-resolution.rst @@ -21,7 +21,7 @@ source unit is assigned a unique *source unit name* which is an opaque and unstr When you use the :ref:`import statement `, you specify an *import path* that references a source unit name. -.. index:: ! import callback, ! Host Filesystem Loader +.. index:: ! import callback, ! Host Filesystem Loader, ! --no-import-callback .. _import-callback: Import Callback @@ -36,8 +36,9 @@ An import callback is free to interpret source unit names in an arbitrary way, n If there is no callback available when one is needed or if it fails to locate the source code, compilation fails. -The command-line compiler provides the *Host Filesystem Loader* - a rudimentary callback +By default, the command-line compiler provides the *Host Filesystem Loader* - a rudimentary callback that interprets a source unit name as a path in the local filesystem. +This callback can be disabled using the ``--no-import-callback`` command-line option. The `JavaScript interface `_ does not provide any by default, but one can be provided by the user. This mechanism can be used to obtain source code from locations other then the local filesystem @@ -515,7 +516,7 @@ you can use the following in your source file: The compiler will look for the file in the VFS under ``dapp-bin/library/math.sol``. If the file is not available there, the source unit name will be passed to the Host Filesystem -Loader, which will then look in ``/project/dapp-bin/library/iterable_mapping.sol``. +Loader, which will then look in ``/project/dapp-bin/library/math.sol``. .. warning:: diff --git a/docs/solidity_logo.svg b/docs/solidity_logo.svg new file mode 100644 index 000000000000..86b9f4995b24 --- /dev/null +++ b/docs/solidity_logo.svg @@ -0,0 +1,27 @@ + + + + +Vector 1 +Created with Sketch. + + + + + + + + + + + + + diff --git a/docs/structure-of-a-contract.rst b/docs/structure-of-a-contract.rst index 740cce861afb..51d99a803602 100644 --- a/docs/structure-of-a-contract.rst +++ b/docs/structure-of-a-contract.rst @@ -112,11 +112,11 @@ Events are convenience interfaces with the EVM logging facilities. .. code-block:: solidity // SPDX-License-Identifier: GPL-3.0 - pragma solidity >=0.4.21 <0.9.0; + pragma solidity ^0.8.22; - contract SimpleAuction { - event HighestBidIncreased(address bidder, uint amount); // Event + event HighestBidIncreased(address bidder, uint amount); // Event + contract SimpleAuction { function bid() public payable { // ... emit HighestBidIncreased(msg.sender, msg.value); // Triggering event diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 266c1817f4f0..427ede5ee3da 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -233,7 +233,7 @@ Yes: bytes32[] options ); - LongAndLotsOfArgs( + emit LongAndLotsOfArgs( sender, recipient, publicKey, @@ -251,7 +251,7 @@ No: uint256 amount, bytes32[] options); - LongAndLotsOfArgs(sender, + emit LongAndLotsOfArgs(sender, recipient, publicKey, amount, @@ -1045,13 +1045,15 @@ No: Order of Layout *************** -Layout contract elements in the following order: +Contract elements should be laid out in the following order: 1. Pragma statements 2. Import statements -3. Interfaces -4. Libraries -5. Contracts +3. Events +4. Errors +5. Interfaces +6. Libraries +7. Contracts Inside each contract, library or interface, use the following order: diff --git a/docs/types/reference-types.rst b/docs/types/reference-types.rst index a136497e63aa..d2e9300e64a4 100644 --- a/docs/types/reference-types.rst +++ b/docs/types/reference-types.rst @@ -372,7 +372,7 @@ Array Members .. note:: In EVM versions before Byzantium, it was not possible to access - dynamic arrays return from function calls. If you call functions + dynamic arrays returned from function calls. If you call functions that return dynamic arrays, make sure to use an EVM that is set to Byzantium mode. diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 3c0c1a70b609..0adcbf4132bb 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -147,14 +147,14 @@ Target Options Below is a list of target EVM versions and the compiler-relevant changes introduced at each version. Backward compatibility is not guaranteed between each version. -- ``homestead`` +- ``homestead`` (*support deprecated*) - (oldest version) -- ``tangerineWhistle`` +- ``tangerineWhistle`` (*support deprecated*) - Gas cost for access to other accounts increased, relevant for gas estimation and the optimizer. - All gas sent by default for external calls, previously a certain amount had to be retained. -- ``spuriousDragon`` +- ``spuriousDragon`` (*support deprecated*) - Gas cost for the ``exp`` opcode increased, relevant for gas estimation and the optimizer. -- ``byzantium`` +- ``byzantium`` (*support deprecated*) - Opcodes ``returndatacopy``, ``returndatasize`` and ``staticcall`` are available in assembly. - The ``staticcall`` opcode is used when calling non-library view or pure functions, which prevents the functions from modifying state at the EVM level, i.e., even applies when you use invalid type conversions. - It is possible to access dynamic data returned from function calls. @@ -175,7 +175,7 @@ at each version. Backward compatibility is not guaranteed between each version. - ``paris`` - Introduces ``prevrandao()`` and ``block.prevrandao``, and changes the semantics of the now deprecated ``block.difficulty``, disallowing ``difficulty()`` in inline assembly (see `EIP-4399 `_). - ``shanghai`` (**default**) - - Smaller code size and gas savings due to the introduction of ``push0`` (see `EIP-3855 `_). + - Smaller code size and gas savings due to the introduction of ``push0`` (see `EIP-3855 `_). .. index:: ! standard JSON, ! --standard-json .. _compiler-api: @@ -287,6 +287,9 @@ Input Description "cse": false, // Optimize representation of literal numbers and strings in code. "constantOptimizer": false, + // Use unchecked arithmetic when incrementing the counter of for loops + // under certain circumstances. It is always on if no details are given. + "simpleCounterForLoopUncheckedIncrement": true, // The new Yul optimizer. Mostly operates on the code of ABI coder v2 // and inline assembly. // It is activated together with the global optimizer setting @@ -318,7 +321,7 @@ Input Description // Affects type checking and code generation. Can be homestead, // tangerineWhistle, spuriousDragon, byzantium, constantinople, // petersburg, istanbul, berlin, london, paris or shanghai (default) - "evmVersion": "byzantium", + "evmVersion": "shanghai", // Optional: Change compilation pipeline to go through the Yul intermediate representation. // This is false by default. "viaIR": true, @@ -359,7 +362,7 @@ Input Description // Addresses of the libraries. If not all libraries are given here, // it can result in unlinked objects whose output data is different. "libraries": { - // The top level key is the the name of the source file where the library is used. + // The top level key is the name of the source file where the library is used. // If remappings are used, this source file should match the global path // after remappings were applied. // If this key is an empty string, that refers to a global level. @@ -408,7 +411,7 @@ Input Description // evm.methodIdentifiers - The list of function hashes // evm.gasEstimates - Function gas estimates // - // Note that using a using `evm`, `evm.bytecode`, etc. will select every + // Note that using `evm`, `evm.bytecode`, etc. will select every // target part of that output. Additionally, `*` can be used as a wildcard to request everything. // "outputSelection": { diff --git a/docs/yul.rst b/docs/yul.rst index 3c94345e14d6..b025ca2377d5 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -741,7 +741,7 @@ EVM Dialect ----------- The default dialect of Yul currently is the EVM dialect for the currently selected version of the EVM. -with a version of the EVM. The only type available in this dialect +The only type available in this dialect is ``u256``, the 256-bit native type of the Ethereum Virtual Machine. Since it is the default type of this dialect, it can be omitted. diff --git a/libevmasm/AbstractAssemblyStack.h b/libevmasm/AbstractAssemblyStack.h new file mode 100644 index 000000000000..6be78cbc7cac --- /dev/null +++ b/libevmasm/AbstractAssemblyStack.h @@ -0,0 +1,54 @@ +/* + 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 . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +#include +#include + +#include +#include + +namespace solidity::evmasm +{ + +class AbstractAssemblyStack +{ +public: + virtual ~AbstractAssemblyStack() {} + + virtual LinkerObject const& object(std::string const& _contractName) const = 0; + virtual LinkerObject const& runtimeObject(std::string const& _contractName) const = 0; + + virtual std::string const* sourceMapping(std::string const& _contractName) const = 0; + virtual std::string const* runtimeSourceMapping(std::string const& _contractName) const = 0; + + virtual Json::Value assemblyJSON(std::string const& _contractName) const = 0; + virtual std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const = 0; + + virtual std::string const filesystemFriendlyName(std::string const& _contractName) const = 0; + + virtual std::vector contractNames() const = 0; + virtual std::vector sourceNames() const = 0; + + virtual bool compilationSuccessful() const = 0; +}; + +} // namespace solidity::evmasm diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index f524aad66b8a..b6e4d0006c57 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -34,19 +34,27 @@ #include #include -#include +#include +#include + +#include #include +#include #include +#include #include #include +#include using namespace solidity; using namespace solidity::evmasm; using namespace solidity::langutil; using namespace solidity::util; +std::map> Assembly::s_sharedSourceNames; + AssemblyItem const& Assembly::append(AssemblyItem _i) { assertThrow(m_deposit >= 0, AssemblyException, "Stack underflow."); @@ -73,6 +81,205 @@ unsigned Assembly::codeSize(unsigned subTagSize) const } } +void Assembly::importAssemblyItemsFromJSON(Json::Value const& _code, std::vector const& _sourceList) +{ + solAssert(m_items.empty()); + solRequire(_code.isArray(), AssemblyImportException, "Supplied JSON is not an array."); + for (auto jsonItemIter = std::begin(_code); jsonItemIter != std::end(_code); ++jsonItemIter) + { + AssemblyItem const& newItem = m_items.emplace_back(createAssemblyItemFromJSON(*jsonItemIter, _sourceList)); + if (newItem == Instruction::JUMPDEST) + solThrow(AssemblyImportException, "JUMPDEST instruction without a tag"); + else if (newItem.type() == AssemblyItemType::Tag) + { + ++jsonItemIter; + if (jsonItemIter != std::end(_code) && createAssemblyItemFromJSON(*jsonItemIter, _sourceList) != Instruction::JUMPDEST) + solThrow(AssemblyImportException, "JUMPDEST expected after tag."); + } + } +} + +AssemblyItem Assembly::createAssemblyItemFromJSON(Json::Value const& _json, std::vector const& _sourceList) +{ + solRequire(_json.isObject(), AssemblyImportException, "Supplied JSON is not an object."); + static std::set const validMembers{"name", "begin", "end", "source", "value", "modifierDepth", "jumpType"}; + for (std::string const& member: _json.getMemberNames()) + solRequire( + validMembers.count(member), + AssemblyImportException, + fmt::format( + "Unknown member '{}'. Valid members are: {}.", + member, + solidity::util::joinHumanReadable(validMembers, ", ") + ) + ); + solRequire(isOfType(_json["name"]), AssemblyImportException, "Member 'name' missing or not of type string."); + solRequire(isOfTypeIfExists(_json, "begin"), AssemblyImportException, "Optional member 'begin' not of type int."); + solRequire(isOfTypeIfExists(_json, "end"), AssemblyImportException, "Optional member 'end' not of type int."); + solRequire(isOfTypeIfExists(_json, "source"), AssemblyImportException, "Optional member 'source' not of type int."); + solRequire(isOfTypeIfExists(_json, "value"), AssemblyImportException, "Optional member 'value' not of type string."); + solRequire(isOfTypeIfExists(_json, "modifierDepth"), AssemblyImportException, "Optional member 'modifierDepth' not of type int."); + solRequire(isOfTypeIfExists(_json, "jumpType"), AssemblyImportException, "Optional member 'jumpType' not of type string."); + + std::string name = get(_json["name"]); + solRequire(!name.empty(), AssemblyImportException, "Member 'name' is empty."); + + SourceLocation location; + location.start = get(_json["begin"]); + location.end = get(_json["end"]); + int srcIndex = getOrDefault(_json["source"], -1); + size_t modifierDepth = static_cast(getOrDefault(_json["modifierDepth"], 0)); + std::string value = getOrDefault(_json["value"], ""); + std::string jumpType = getOrDefault(_json["jumpType"], ""); + + auto updateUsedTags = [&](u256 const& data) + { + m_usedTags = std::max(m_usedTags, static_cast(data) + 1); + return data; + }; + + auto storeImmutableHash = [&](std::string const& _immutableName) -> h256 + { + h256 hash(util::keccak256(_immutableName)); + solAssert(m_immutables.count(hash) == 0 || m_immutables[hash] == _immutableName); + m_immutables[hash] = _immutableName; + return hash; + }; + + auto storeLibraryHash = [&](std::string const& _libraryName) -> h256 + { + h256 hash(util::keccak256(_libraryName)); + solAssert(m_libraries.count(hash) == 0 || m_libraries[hash] == _libraryName); + m_libraries[hash] = _libraryName; + return hash; + }; + + auto requireValueDefinedForInstruction = [&](std::string const& _name, std::string const& _value) + { + solRequire( + !_value.empty(), + AssemblyImportException, + "Member 'value' is missing for instruction '" + _name + "', but the instruction needs a value." + ); + }; + + auto requireValueUndefinedForInstruction = [&](std::string const& _name, std::string const& _value) + { + solRequire( + _value.empty(), + AssemblyImportException, + "Member 'value' defined for instruction '" + _name + "', but the instruction does not need a value." + ); + }; + + solRequire(srcIndex >= -1 && srcIndex < static_cast(_sourceList.size()), AssemblyImportException, "Source index out of bounds."); + if (srcIndex != -1) + location.sourceName = sharedSourceName(_sourceList[static_cast(srcIndex)]); + + AssemblyItem result(0); + + if (c_instructions.count(name)) + { + AssemblyItem item{c_instructions.at(name), location}; + if (!jumpType.empty()) + { + if (item.instruction() == Instruction::JUMP || item.instruction() == Instruction::JUMPI) + { + std::optional parsedJumpType = AssemblyItem::parseJumpType(jumpType); + if (!parsedJumpType.has_value()) + solThrow(AssemblyImportException, "Invalid jump type."); + item.setJumpType(parsedJumpType.value()); + } + else + solThrow( + AssemblyImportException, + "Member 'jumpType' set on instruction different from JUMP or JUMPI (was set on instruction '" + name + "')" + ); + } + requireValueUndefinedForInstruction(name, value); + result = item; + } + else + { + solRequire( + jumpType.empty(), + AssemblyImportException, + "Member 'jumpType' set on instruction different from JUMP or JUMPI (was set on instruction '" + name + "')" + ); + if (name == "PUSH") + { + requireValueDefinedForInstruction(name, value); + result = {AssemblyItemType::Push, u256("0x" + value)}; + } + else if (name == "PUSH [ErrorTag]") + { + requireValueUndefinedForInstruction(name, value); + result = {AssemblyItemType::PushTag, 0}; + } + else if (name == "PUSH [tag]") + { + requireValueDefinedForInstruction(name, value); + result = {AssemblyItemType::PushTag, updateUsedTags(u256(value))}; + } + else if (name == "PUSH [$]") + { + requireValueDefinedForInstruction(name, value); + result = {AssemblyItemType::PushSub, u256("0x" + value)}; + } + else if (name == "PUSH #[$]") + { + requireValueDefinedForInstruction(name, value); + result = {AssemblyItemType::PushSubSize, u256("0x" + value)}; + } + else if (name == "PUSHSIZE") + { + requireValueUndefinedForInstruction(name, value); + result = {AssemblyItemType::PushProgramSize, 0}; + } + else if (name == "PUSHLIB") + { + requireValueDefinedForInstruction(name, value); + result = {AssemblyItemType::PushLibraryAddress, storeLibraryHash(value)}; + } + else if (name == "PUSHDEPLOYADDRESS") + { + requireValueUndefinedForInstruction(name, value); + result = {AssemblyItemType::PushDeployTimeAddress, 0}; + } + else if (name == "PUSHIMMUTABLE") + { + requireValueDefinedForInstruction(name, value); + result = {AssemblyItemType::PushImmutable, storeImmutableHash(value)}; + } + else if (name == "ASSIGNIMMUTABLE") + { + requireValueDefinedForInstruction(name, value); + result = {AssemblyItemType::AssignImmutable, storeImmutableHash(value)}; + } + else if (name == "tag") + { + requireValueDefinedForInstruction(name, value); + result = {AssemblyItemType::Tag, updateUsedTags(u256(value))}; + } + else if (name == "PUSH data") + { + requireValueDefinedForInstruction(name, value); + result = {AssemblyItemType::PushData, u256("0x" + value)}; + } + else if (name == "VERBATIM") + { + requireValueDefinedForInstruction(name, value); + AssemblyItem item(fromHex(value), 0, 0); + result = item; + } + else + solThrow(InvalidOpcode, "Invalid opcode: " + name); + } + result.setLocation(location); + result.m_modifierDepth = modifierDepth; + return result; +} + namespace { @@ -297,6 +504,154 @@ Json::Value Assembly::assemblyJSON(std::map const& _sourc return root; } +std::pair, std::vector> Assembly::fromJSON( + Json::Value const& _json, + std::vector const& _sourceList, + size_t _level +) +{ + solRequire(_json.isObject(), AssemblyImportException, "Supplied JSON is not an object."); + static std::set const validMembers{".code", ".data", ".auxdata", "sourceList"}; + for (std::string const& attribute: _json.getMemberNames()) + solRequire(validMembers.count(attribute), AssemblyImportException, "Unknown attribute '" + attribute + "'."); + + if (_level == 0) + { + if (_json.isMember("sourceList")) + { + solRequire(_json["sourceList"].isArray(), AssemblyImportException, "Optional member 'sourceList' is not an array."); + for (Json::Value const& sourceName: _json["sourceList"]) + solRequire(sourceName.isString(), AssemblyImportException, "The 'sourceList' array contains an item that is not a string."); + } + } + else + solRequire( + !_json.isMember("sourceList"), + AssemblyImportException, + "Member 'sourceList' may only be present in the root JSON object." + ); + + auto result = std::make_shared(EVMVersion{}, _level == 0 /* _creation */, "" /* _name */); + std::vector parsedSourceList; + if (_json.isMember("sourceList")) + { + solAssert(_level == 0); + solAssert(_sourceList.empty()); + for (Json::Value const& sourceName: _json["sourceList"]) + { + solRequire( + std::find(parsedSourceList.begin(), parsedSourceList.end(), sourceName.asString()) == parsedSourceList.end(), + AssemblyImportException, + "Items in 'sourceList' array are not unique." + ); + parsedSourceList.emplace_back(sourceName.asString()); + } + } + + solRequire(_json.isMember(".code"), AssemblyImportException, "Member '.code' is missing."); + solRequire(_json[".code"].isArray(), AssemblyImportException, "Member '.code' is not an array."); + for (Json::Value const& codeItem: _json[".code"]) + solRequire(codeItem.isObject(), AssemblyImportException, "The '.code' array contains an item that is not an object."); + + result->importAssemblyItemsFromJSON(_json[".code"], _level == 0 ? parsedSourceList : _sourceList); + + if (_json[".auxdata"]) + { + solRequire(_json[".auxdata"].isString(), AssemblyImportException, "Optional member '.auxdata' is not a string."); + result->m_auxiliaryData = fromHex(_json[".auxdata"].asString()); + solRequire(!result->m_auxiliaryData.empty(), AssemblyImportException, "Optional member '.auxdata' is not a valid hexadecimal string."); + } + + if (_json.isMember(".data")) + { + solRequire(_json[".data"].isObject(), AssemblyImportException, "Optional member '.data' is not an object."); + Json::Value const& data = _json[".data"]; + std::map> subAssemblies; + for (Json::ValueConstIterator dataIter = data.begin(); dataIter != data.end(); dataIter++) + { + solAssert(dataIter.key().isString()); + std::string dataItemID = dataIter.key().asString(); + Json::Value const& dataItem = data[dataItemID]; + if (dataItem.isString()) + { + solRequire( + dataItem.asString().empty() || !fromHex(dataItem.asString()).empty(), + AssemblyImportException, + "The value for key '" + dataItemID + "' inside '.data' is not a valid hexadecimal string." + ); + result->m_data[h256(fromHex(dataItemID))] = fromHex(dataItem.asString()); + } + else if (dataItem.isObject()) + { + size_t index{}; + try + { + // Using signed variant because stoul() still accepts negative numbers and + // just lets them wrap around. + int parsedDataItemID = std::stoi(dataItemID, nullptr, 16); + solRequire(parsedDataItemID >= 0, AssemblyImportException, "The key '" + dataItemID + "' inside '.data' is out of the supported integer range."); + index = static_cast(parsedDataItemID); + } + catch (std::invalid_argument const&) + { + solThrow(AssemblyImportException, "The key '" + dataItemID + "' inside '.data' is not an integer."); + } + catch (std::out_of_range const&) + { + solThrow(AssemblyImportException, "The key '" + dataItemID + "' inside '.data' is out of the supported integer range."); + } + + auto [subAssembly, emptySourceList] = Assembly::fromJSON(dataItem, _level == 0 ? parsedSourceList : _sourceList, _level + 1); + solAssert(subAssembly); + solAssert(emptySourceList.empty()); + solAssert(subAssemblies.count(index) == 0); + subAssemblies[index] = subAssembly; + } + else + solThrow(AssemblyImportException, "The value of key '" + dataItemID + "' inside '.data' is neither a hex string nor an object."); + } + + if (!subAssemblies.empty()) + solRequire( + ranges::max(subAssemblies | ranges::views::keys) == subAssemblies.size() - 1, + AssemblyImportException, + fmt::format( + "Invalid subassembly indices in '.data'. Not all numbers between 0 and {} are present.", + subAssemblies.size() - 1 + ) + ); + + result->m_subs = subAssemblies | ranges::views::values | ranges::to; + } + + if (_level == 0) + result->encodeAllPossibleSubPathsInAssemblyTree(); + + return std::make_pair(result, _level == 0 ? parsedSourceList : std::vector{}); +} + +void Assembly::encodeAllPossibleSubPathsInAssemblyTree(std::vector _pathFromRoot, std::vector _assembliesOnPath) +{ + _assembliesOnPath.push_back(this); + for (_pathFromRoot.push_back(0); _pathFromRoot.back() < m_subs.size(); ++_pathFromRoot.back()) + { + for (size_t distanceFromRoot = 0; distanceFromRoot < _assembliesOnPath.size(); ++distanceFromRoot) + _assembliesOnPath[distanceFromRoot]->encodeSubPath( + _pathFromRoot | ranges::views::drop_exactly(distanceFromRoot) | ranges::to + ); + + m_subs[_pathFromRoot.back()]->encodeAllPossibleSubPathsInAssemblyTree(_pathFromRoot, _assembliesOnPath); + } +} + +std::shared_ptr Assembly::sharedSourceName(std::string const& _name) const +{ + if (s_sharedSourceNames.find(_name) == s_sharedSourceNames.end()) + s_sharedSourceNames[_name] = std::make_shared(_name); + + return s_sharedSourceNames[_name]; +} + AssemblyItem Assembly::namedTag(std::string const& _name, size_t _params, size_t _returns, std::optional _sourceID) { assertThrow(!_name.empty(), AssemblyException, "Empty named tag."); diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index bd37b3a7fd96..6e900282569b 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -150,10 +150,23 @@ class Assembly ) const; /// Create a JSON representation of the assembly. - Json::Value assemblyJSON( - std::map const& _sourceIndices = std::map(), - bool _includeSourceList = true - ) const; + Json::Value assemblyJSON(std::map const& _sourceIndices, bool _includeSourceList = true) const; + + /// Constructs an @a Assembly from the serialized JSON representation. + /// @param _json JSON object containing assembly in the format produced by assemblyJSON(). + /// @param _sourceList List of source files the assembly was built from. When the JSON represents + /// the root assembly, the function will read it from the 'sourceList' field and the parameter + /// must be empty. It is only used to pass the list down to recursive calls. + /// @param _level Nesting level of the current assembly in the assembly tree. The root is + /// at level 0 and the value increases down the tree. Necessary to distinguish between creation + /// and deployed objects. + /// @returns Created @a Assembly and the source list read from the 'sourceList' field of the root + /// assembly or an empty list (in recursive calls). + static std::pair, std::vector> fromJSON( + Json::Value const& _json, + std::vector const& _sourceList = {}, + size_t _level = 0 + ); /// Mark this assembly as invalid. Calling ``assemble`` on it will throw. void markAsInvalid() { m_invalid = true; } @@ -171,11 +184,27 @@ class Assembly unsigned codeSize(unsigned subTagSize) const; + /// Add all assembly items from given JSON array. This function imports the items by iterating through + /// the code array. This method only works on clean Assembly objects that don't have any items defined yet. + /// @param _json JSON array that contains assembly items (e.g. json['.code']) + /// @param _sourceList List of source names. + void importAssemblyItemsFromJSON(Json::Value const& _code, std::vector const& _sourceList); + + /// Creates an AssemblyItem from a given JSON representation. + /// @param _json JSON object that consists a single assembly item + /// @param _sourceList List of source names. + /// @returns AssemblyItem of _json argument. + AssemblyItem createAssemblyItemFromJSON(Json::Value const& _json, std::vector const& _sourceList); + private: bool m_invalid = false; Assembly const* subAssemblyById(size_t _subId) const; + void encodeAllPossibleSubPathsInAssemblyTree(std::vector _pathFromRoot = {}, std::vector _assembliesOnPath = {}); + + std::shared_ptr sharedSourceName(std::string const& _name) const; + protected: /// 0 is reserved for exception unsigned m_usedTags = 1; @@ -217,9 +246,11 @@ class Assembly /// Internal name of the assembly object, only used with the Yul backend /// currently std::string m_name; - langutil::SourceLocation m_currentSourceLocation; + // FIXME: This being static means that the strings won't be freed when they're no longer needed + static std::map> s_sharedSourceNames; + public: size_t m_currentModifierDepth = 0; }; diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp index 6c2b673c697d..2adaa023a13e 100644 --- a/libevmasm/AssemblyItem.cpp +++ b/libevmasm/AssemblyItem.cpp @@ -247,6 +247,18 @@ std::string AssemblyItem::getJumpTypeAsString() const } } +std::optional AssemblyItem::parseJumpType(std::string const& _jumpType) +{ + if (_jumpType == "[in]") + return JumpType::IntoFunction; + else if (_jumpType == "[out]") + return JumpType::OutOfFunction; + else if (_jumpType.empty()) + return JumpType::Ordinary; + + return std::nullopt; +} + std::string AssemblyItem::toAssemblyText(Assembly const& _assembly) const { std::string text; diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 077c1912d2a8..40f98dae875c 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -174,6 +174,7 @@ class AssemblyItem langutil::SourceLocation const& location() const { return m_location; } void setJumpType(JumpType _jumpType) { m_jumpType = _jumpType; } + static std::optional parseJumpType(std::string const& _jumpType); JumpType getJumpType() const { return m_jumpType; } std::string getJumpTypeAsString() const; diff --git a/libevmasm/CMakeLists.txt b/libevmasm/CMakeLists.txt index 6563b2c0fa13..c1918540e625 100644 --- a/libevmasm/CMakeLists.txt +++ b/libevmasm/CMakeLists.txt @@ -1,8 +1,11 @@ set(sources + AbstractAssemblyStack.h Assembly.cpp Assembly.h AssemblyItem.cpp AssemblyItem.h + EVMAssemblyStack.cpp + EVMAssemblyStack.h BlockDeduplicator.cpp BlockDeduplicator.h CommonSubexpressionEliminator.cpp diff --git a/libevmasm/EVMAssemblyStack.cpp b/libevmasm/EVMAssemblyStack.cpp new file mode 100644 index 000000000000..68f60808c9d5 --- /dev/null +++ b/libevmasm/EVMAssemblyStack.cpp @@ -0,0 +1,122 @@ +/* + 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 . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include +#include +#include + +#include +#include + +#include + +using namespace solidity::util; +using namespace solidity::langutil; +using namespace solidity::frontend; + +namespace solidity::evmasm +{ + +void EVMAssemblyStack::parseAndAnalyze(std::string const& _sourceName, std::string const& _source) +{ + solAssert(!m_evmAssembly); + m_name = _sourceName; + Json::Value assemblyJson; + solRequire(jsonParseStrict(_source, assemblyJson), AssemblyImportException, "Could not parse JSON file."); + std::tie(m_evmAssembly, m_sourceList) = evmasm::Assembly::fromJSON(assemblyJson); + solRequire(m_evmAssembly != nullptr, AssemblyImportException, "Could not create evm assembly object."); +} + +void EVMAssemblyStack::assemble() +{ + solAssert(m_evmAssembly); + solAssert(m_evmAssembly->isCreation()); + solAssert(!m_evmRuntimeAssembly); + + m_object = m_evmAssembly->assemble(); + m_sourceMapping = AssemblyItem::computeSourceMapping(m_evmAssembly->items(), sourceIndices()); + if (m_evmAssembly->numSubs() > 0) + { + m_evmRuntimeAssembly = std::make_shared(m_evmAssembly->sub(0)); + solAssert(m_evmRuntimeAssembly && !m_evmRuntimeAssembly->isCreation()); + m_runtimeSourceMapping = AssemblyItem::computeSourceMapping(m_evmRuntimeAssembly->items(), sourceIndices()); + m_runtimeObject = m_evmRuntimeAssembly->assemble(); + } +} + +LinkerObject const& EVMAssemblyStack::object(std::string const& _contractName) const +{ + solAssert(_contractName == m_name); + return m_object; +} + +LinkerObject const& EVMAssemblyStack::runtimeObject(std::string const& _contractName) const +{ + solAssert(_contractName == m_name); + return m_runtimeObject; +} + +std::map EVMAssemblyStack::sourceIndices() const +{ + solAssert(m_evmAssembly); + return m_sourceList + | ranges::views::enumerate + | ranges::views::transform([](auto const& _source) { return std::make_pair(_source.second, _source.first); }) + | ranges::to>; +} + +std::string const* EVMAssemblyStack::sourceMapping(std::string const& _contractName) const +{ + solAssert(_contractName == m_name); + return &m_sourceMapping; +} + +std::string const* EVMAssemblyStack::runtimeSourceMapping(std::string const& _contractName) const +{ + solAssert(_contractName == m_name); + return &m_runtimeSourceMapping; +} + +Json::Value EVMAssemblyStack::assemblyJSON(std::string const& _contractName) const +{ + solAssert(_contractName == m_name); + solAssert(m_evmAssembly); + return m_evmAssembly->assemblyJSON(sourceIndices()); +} + +std::string EVMAssemblyStack::assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const +{ + solAssert(_contractName == m_name); + solAssert(m_evmAssembly); + return m_evmAssembly->assemblyString(m_debugInfoSelection, _sourceCodes); +} + +std::string const EVMAssemblyStack::filesystemFriendlyName(std::string const& _contractName) const +{ + solAssert(_contractName == m_name); + return m_name; +} + +std::vector EVMAssemblyStack::sourceNames() const +{ + return m_sourceList; +} + +} // namespace solidity::evmasm diff --git a/libevmasm/EVMAssemblyStack.h b/libevmasm/EVMAssemblyStack.h new file mode 100644 index 000000000000..cf02cec52f2c --- /dev/null +++ b/libevmasm/EVMAssemblyStack.h @@ -0,0 +1,85 @@ +/* + 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 . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include +#include + +#include + +#include +#include + +namespace solidity::evmasm +{ + +class EVMAssemblyStack: public AbstractAssemblyStack +{ +public: + explicit EVMAssemblyStack(langutil::EVMVersion _evmVersion): m_evmVersion(_evmVersion) {} + + /// Runs parsing and analysis steps. + /// Multiple calls overwrite the previous state. + /// @throws AssemblyImportException, if JSON could not be validated. + void parseAndAnalyze(std::string const& _sourceName, std::string const& _source); + + void assemble(); + + std::string const& name() const { return m_name; } + + virtual LinkerObject const& object(std::string const& _contractName) const override; + virtual LinkerObject const& runtimeObject(std::string const& _contractName) const override; + + std::shared_ptr const& evmAssembly() const { return m_evmAssembly; } + std::shared_ptr const& evmRuntimeAssembly() const { return m_evmRuntimeAssembly; } + + virtual std::string const* sourceMapping(std::string const& _contractName) const override; + virtual std::string const* runtimeSourceMapping(std::string const& _contractName) const override; + + virtual Json::Value assemblyJSON(std::string const& _contractName) const override; + virtual std::string assemblyString(std::string const& _contractName, StringMap const& _sourceCodes) const override; + + virtual std::string const filesystemFriendlyName(std::string const& _contractName) const override; + + virtual std::vector contractNames() const override { return {m_name}; } + virtual std::vector sourceNames() const override; + std::map sourceIndices() const; + + virtual bool compilationSuccessful() const override { return m_evmAssembly != nullptr; } + + void selectDebugInfo(langutil::DebugInfoSelection _debugInfoSelection) + { + m_debugInfoSelection = _debugInfoSelection; + } + +private: + langutil::EVMVersion m_evmVersion; + std::string m_name; + std::shared_ptr m_evmAssembly; + std::shared_ptr m_evmRuntimeAssembly; + evmasm::LinkerObject m_object; ///< Deployment object (includes the runtime sub-object). + evmasm::LinkerObject m_runtimeObject; ///< Runtime object. + std::vector m_sourceList; + langutil::DebugInfoSelection m_debugInfoSelection = langutil::DebugInfoSelection::Default(); + std::string m_sourceMapping; + std::string m_runtimeSourceMapping; +}; + +} // namespace solidity::evmasm diff --git a/libevmasm/Exceptions.h b/libevmasm/Exceptions.h index 02757757602e..ae6d1bf9c617 100644 --- a/libevmasm/Exceptions.h +++ b/libevmasm/Exceptions.h @@ -28,6 +28,7 @@ namespace solidity::evmasm { struct AssemblyException: virtual util::Exception {}; +struct AssemblyImportException: virtual AssemblyException {}; struct OptimizerException: virtual AssemblyException {}; struct StackTooDeepException: virtual OptimizerException {}; struct ItemNotAvailableException: virtual OptimizerException {}; diff --git a/libevmasm/KnownState.h b/libevmasm/KnownState.h index 8c28fbb62277..9cc22710fabe 100644 --- a/libevmasm/KnownState.h +++ b/libevmasm/KnownState.h @@ -109,7 +109,7 @@ class KnownState /// 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(); } diff --git a/liblangutil/Exceptions.cpp b/liblangutil/Exceptions.cpp index 118720b74570..108acd1216ee 100644 --- a/liblangutil/Exceptions.cpp +++ b/liblangutil/Exceptions.cpp @@ -29,6 +29,26 @@ using namespace solidity; using namespace solidity::langutil; +std::map const Error::m_errorTypeNames = { + {Error::Type::IOError, "IOError"}, + {Error::Type::FatalError, "FatalError"}, + {Error::Type::JSONError, "JSONError"}, + {Error::Type::InternalCompilerError, "InternalCompilerError"}, + {Error::Type::CompilerError, "CompilerError"}, + {Error::Type::Exception, "Exception"}, + {Error::Type::CodeGenerationError, "CodeGenerationError"}, + {Error::Type::DeclarationError, "DeclarationError"}, + {Error::Type::DocstringParsingError, "DocstringParsingError"}, + {Error::Type::ParserError, "ParserError"}, + {Error::Type::SyntaxError, "SyntaxError"}, + {Error::Type::TypeError, "TypeError"}, + {Error::Type::UnimplementedFeatureError, "UnimplementedFeatureError"}, + {Error::Type::YulException, "YulException"}, + {Error::Type::SMTLogicException, "SMTLogicException"}, + {Error::Type::Warning, "Warning"}, + {Error::Type::Info, "Info"}, +}; + Error::Error( ErrorId _errorId, Error::Type _type, std::string const& _description, diff --git a/liblangutil/Exceptions.h b/liblangutil/Exceptions.h index fc7286ed1c73..b0701f99938e 100644 --- a/liblangutil/Exceptions.h +++ b/liblangutil/Exceptions.h @@ -33,11 +33,11 @@ #include #include +#include #include #include -#include -#include #include +#include namespace solidity::langutil { @@ -170,6 +170,8 @@ class Error: virtual public util::Exception public: enum class Type { + Info, + Warning, CodeGenerationError, DeclarationError, DocstringParsingError, @@ -185,15 +187,14 @@ class Error: virtual public util::Exception 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 @@ class Error: virtual public util::Exception 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; @@ -267,27 +269,17 @@ class Error: virtual public util::Exception static std::string formatErrorType(Type _type) { - switch (_type) - { - case Type::IOError: return "IOError"; - case Type::FatalError: return "FatalError"; - case Type::JSONError: return "JSONError"; - case Type::InternalCompilerError: return "InternalCompilerError"; - case Type::CompilerError: return "CompilerError"; - case Type::Exception: return "Exception"; - case Type::CodeGenerationError: return "CodeGenerationError"; - case Type::DeclarationError: return "DeclarationError"; - case Type::DocstringParsingError: return "DocstringParsingError"; - case Type::ParserError: return "ParserError"; - case Type::SyntaxError: return "SyntaxError"; - case Type::TypeError: return "TypeError"; - case Type::UnimplementedFeatureError: return "UnimplementedFeatureError"; - case Type::YulException: return "YulException"; - case Type::SMTLogicException: return "SMTLogicException"; - case Type::Warning: return "Warning"; - case Type::Info: return "Info"; - } - util::unreachable(); + return m_errorTypeNames.at(_type); + } + + static std::optional parseErrorType(std::string _name) + { + static std::map const m_errorTypesByName = util::invertMap(m_errorTypeNames); + + if (m_errorTypesByName.count(_name) == 0) + return std::nullopt; + + return m_errorTypesByName.at(_name); } static std::string formatTypeOrSeverity(std::variant _typeOrSeverity) @@ -307,6 +299,8 @@ class Error: virtual public util::Exception private: ErrorId m_errorId; Type m_type; + + static std::map const m_errorTypeNames; }; } diff --git a/liblangutil/ParserBase.cpp b/liblangutil/ParserBase.cpp index 12a00d04f121..fde0f27ecc5a 100644 --- a/liblangutil/ParserBase.cpp +++ b/liblangutil/ParserBase.cpp @@ -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(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(); } diff --git a/liblangutil/ParserBase.h b/liblangutil/ParserBase.h index f72400f6c34e..88fc76a9c307 100644 --- a/liblangutil/ParserBase.h +++ b/liblangutil/ParserBase.h @@ -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 @@ class ParserBase ///@{ ///@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 @@ class ParserBase 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; }; } diff --git a/liblangutil/Scanner.cpp b/liblangutil/Scanner.cpp index 2d5607607a88..3db3f29d5d23 100644 --- a/liblangutil/Scanner.cpp +++ b/liblangutil/Scanner.cpp @@ -1019,15 +1019,28 @@ std::tuple 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; } diff --git a/liblangutil/Scanner.h b/liblangutil/Scanner.h index c45a2ec243e8..eaa2b3b54d1e 100644 --- a/liblangutil/Scanner.h +++ b/liblangutil/Scanner.h @@ -69,7 +69,8 @@ class ParserRecorder; enum class ScannerKind { Solidity, - Yul + Yul, + ExperimentalSolidity }; enum class ScannerError diff --git a/liblangutil/SourceReferenceFormatter.cpp b/liblangutil/SourceReferenceFormatter.cpp index 76cb1df61a33..c48cb328d5f9 100644 --- a/liblangutil/SourceReferenceFormatter.cpp +++ b/liblangutil/SourceReferenceFormatter.cpp @@ -55,6 +55,28 @@ std::string SourceReferenceFormatter::formatErrorInformation(Error const& _error ); } +char const* SourceReferenceFormatter::errorTextColor(Error::Severity _severity) +{ + switch (_severity) + { + case Error::Severity::Error: return RED; + case Error::Severity::Warning: return YELLOW; + case Error::Severity::Info: return WHITE; + } + util::unreachable(); +} + +char const* SourceReferenceFormatter::errorHighlightColor(Error::Severity _severity) +{ + switch (_severity) + { + case Error::Severity::Error: return RED_BACKGROUND; + case Error::Severity::Warning: return ORANGE_BACKGROUND_256; + case Error::Severity::Info: return GRAY_BACKGROUND; + } + util::unreachable(); +} + AnsiColorized SourceReferenceFormatter::normalColored() const { return AnsiColorized(m_stream, m_colored, {WHITE}); @@ -65,25 +87,14 @@ AnsiColorized SourceReferenceFormatter::frameColored() const return AnsiColorized(m_stream, m_colored, {BOLD, BLUE}); } -AnsiColorized SourceReferenceFormatter::errorColored(Error::Severity _severity) const +AnsiColorized SourceReferenceFormatter::errorColored(std::ostream& _stream, bool _colored, Error::Severity _severity) { - // We used to color messages of any severity as errors so this seems like a good default - // for cases where severity cannot be determined. - char const* textColor = RED; - - switch (_severity) - { - case Error::Severity::Error: textColor = RED; break; - case Error::Severity::Warning: textColor = YELLOW; break; - case Error::Severity::Info: textColor = WHITE; break; - } - - return AnsiColorized(m_stream, m_colored, {BOLD, textColor}); + return AnsiColorized(_stream, _colored, {BOLD, errorTextColor(_severity)}); } -AnsiColorized SourceReferenceFormatter::messageColored() const +AnsiColorized SourceReferenceFormatter::messageColored(std::ostream& _stream, bool _colored) { - return AnsiColorized(m_stream, m_colored, {BOLD, WHITE}); + return AnsiColorized(_stream, _colored, {BOLD, WHITE}); } AnsiColorized SourceReferenceFormatter::secondaryColored() const @@ -175,14 +186,26 @@ void SourceReferenceFormatter::printSourceLocation(SourceReference const& _ref) } } -void SourceReferenceFormatter::printExceptionInformation(SourceReferenceExtractor::Message const& _msg) +void SourceReferenceFormatter::printPrimaryMessage( + std::ostream& _stream, + std::string _message, + std::variant _typeOrSeverity, + std::optional _errorId, + bool _colored, + bool _withErrorIds +) { - errorColored(Error::errorSeverityOrType(_msg._typeOrSeverity)) << Error::formatTypeOrSeverity(_msg._typeOrSeverity); + errorColored(_stream, _colored, Error::errorSeverityOrType(_typeOrSeverity)) << Error::formatTypeOrSeverity(_typeOrSeverity); + + if (_withErrorIds && _errorId.has_value()) + errorColored(_stream, _colored, Error::errorSeverityOrType(_typeOrSeverity)) << " (" << _errorId.value().error << ")"; - if (m_withErrorIds && _msg.errorId.has_value()) - errorColored(Error::errorSeverityOrType(_msg._typeOrSeverity)) << " (" << _msg.errorId.value().error << ")"; + messageColored(_stream, _colored) << ": " << _message << '\n'; +} - messageColored() << ": " << _msg.primary.message << '\n'; +void SourceReferenceFormatter::printExceptionInformation(SourceReferenceExtractor::Message const& _msg) +{ + printPrimaryMessage(m_stream, _msg.primary.message, _msg._typeOrSeverity, _msg.errorId, m_colored, m_withErrorIds); printSourceLocation(_msg.primary); for (auto const& secondary: _msg.secondary) diff --git a/liblangutil/SourceReferenceFormatter.h b/liblangutil/SourceReferenceFormatter.h index def216efa16d..7163199deea1 100644 --- a/liblangutil/SourceReferenceFormatter.h +++ b/liblangutil/SourceReferenceFormatter.h @@ -46,9 +46,16 @@ class SourceReferenceFormatter 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 @@ class SourceReferenceFormatter 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,39 +81,74 @@ class SourceReferenceFormatter util::Exception const& _exception, Error::Severity _severity, CharStreamProvider const& _charStreamProvider, + bool _colored = false + ) + { + std::ostringstream errorOutput; + SourceReferenceFormatter formatter(errorOutput, _charStreamProvider, _colored, false /* _withErrorIds */); + formatter.printExceptionInformation(_exception, _severity); + return errorOutput.str(); + } + + static std::string formatErrorInformation( + Error const& _error, + CharStreamProvider const& _charStreamProvider, bool _colored = false, bool _withErrorIds = false ) { std::ostringstream errorOutput; SourceReferenceFormatter formatter(errorOutput, _charStreamProvider, _colored, _withErrorIds); - formatter.printExceptionInformation(_exception, _severity); + formatter.printErrorInformation(_error); return errorOutput.str(); } static std::string formatErrorInformation( - Error const& _error, - CharStreamProvider const& _charStreamProvider + langutil::ErrorList const& _errors, + 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(_errors); + return errorOutput.str(); } static std::string formatErrorInformation(Error const& _error, CharStream const& _charStream); + static void printPrimaryMessage( + std::ostream& _stream, + std::string _message, + std::variant _typeOrSeverity, + std::optional _errorId = std::nullopt, + bool _colored = false, + bool _withErrorIds = false + ); + + /// The default text color for printing error messages of a given severity in the terminal. + /// Assumes a dark background color. + static char const* errorTextColor(Error::Severity _severity); + + /// The default background color for highlighting source fragments corresponding to an error + /// of a given severity in the terminal. Assumes a light text color. + /// @note This is *not* meant to be used for the same text in combination with @a errorTextColor(). + /// It's an alternative way to highlight it, while preserving the original text color. + static char const* errorHighlightColor(Error::Severity _severity); + private: util::AnsiColorized normalColored() const; util::AnsiColorized frameColored() const; - util::AnsiColorized errorColored(langutil::Error::Severity _severity) const; - util::AnsiColorized messageColored() const; + util::AnsiColorized errorColored(Error::Severity _severity) const { return errorColored(m_stream, m_colored, _severity); } + util::AnsiColorized messageColored() const { return messageColored(m_stream, m_colored); } util::AnsiColorized secondaryColored() const; util::AnsiColorized highlightColored() const; util::AnsiColorized diagColored() const; + static util::AnsiColorized errorColored(std::ostream& _stream, bool _colored, langutil::Error::Severity _severity); + static util::AnsiColorized messageColored(std::ostream& _stream, bool _colored); + private: std::ostream& m_stream; CharStreamProvider const& m_charStreamProvider; diff --git a/liblangutil/Token.h b/liblangutil/Token.h index d84cbe531334..54696275010d 100644 --- a/liblangutil/Token.h +++ b/liblangutil/Token.h @@ -271,6 +271,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) \ \ @@ -327,6 +329,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); diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 32869ba130dc..0a8c90f36bbb 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -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) - diff --git a/libsolidity/analysis/ConstantEvaluator.cpp b/libsolidity/analysis/ConstantEvaluator.cpp index 7fde36ec0ebb..8e18183a81f9 100644 --- a/libsolidity/analysis/ConstantEvaluator.cpp +++ b/libsolidity/analysis/ConstantEvaluator.cpp @@ -29,7 +29,6 @@ #include -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(boost::multiprecision::msb(_base)); + std::size_t mostSignificantBaseBit = static_cast(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 ConstantEvaluator::evaluateBinaryOperator(Token _operator, rational const& _left, rational const& _right) +std::optional 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 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 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 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 ConstantEvaluator::evaluateBinaryOperator(Token _operator, ra } else { - if (abs(exp) > numeric_limits::max()) - return nullopt; // This will need too much memory to represent. + if (abs(exp) > std::numeric_limits::max()) + return std::nullopt; // This will need too much memory to represent. uint32_t absExp = bigint(abs(exp)).convert_to(); 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 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::max()) - return nullopt; + return std::nullopt; + else if (_right > std::numeric_limits::max()) + return std::nullopt; if (_left.numerator() == 0) return 0; else { uint32_t exponent = _right.numerator().convert_to(); 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 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::max()) - return nullopt; + return std::nullopt; + else if (_right > std::numeric_limits::max()) + return std::nullopt; if (_left.numerator() == 0) return 0; else @@ -209,60 +208,60 @@ optional ConstantEvaluator::evaluateBinaryOperator(Token _operator, ra break; } default: - return nullopt; + return std::nullopt; } } -optional ConstantEvaluator::evaluateUnaryOperator(Token _operator, rational const& _input) +std::optional 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 convertType(rational const& _value, Type const& _type) +std::optional 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(&_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 convertType(optional const& _value, Type const& _type) +std::optional convertType(std::optional const& _value, Type const& _type) { - return _value ? convertType(_value->value, _type) : nullopt; + return _value ? convertType(_value->value, _type) : std::nullopt; } -optional constantToTypedValue(Type const& _type) +std::optional constantToTypedValue(Type const& _type) { if (_type.category() == Type::Category::RationalNumber) return TypedRational{&_type, dynamic_cast(_type).value()}; else - return nullopt; + return std::nullopt; } } -optional ConstantEvaluator::evaluate( +std::optional ConstantEvaluator::evaluate( langutil::ErrorReporter& _errorReporter, Expression const& _expr ) @@ -271,7 +270,7 @@ optional ConstantEvaluator::evaluate( } -optional ConstantEvaluator::evaluate(ASTNode const& _node) +std::optional ConstantEvaluator::evaluate(ASTNode const& _node) { if (!m_values.count(&_node)) { @@ -280,7 +279,7 @@ optional 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 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 ConstantEvaluator::evaluate(ASTNode const& _node) void ConstantEvaluator::endVisit(UnaryOperation const& _operation) { - optional value = evaluate(_operation.subExpression()); + std::optional value = evaluate(_operation.subExpression()); if (!value) return; @@ -317,9 +316,9 @@ void ConstantEvaluator::endVisit(UnaryOperation const& _operation) if (!value) return; - if (optional result = evaluateUnaryOperator(_operation.getOperator(), value->value)) + if (std::optional result = evaluateUnaryOperator(_operation.getOperator(), value->value)) { - optional convertedValue = convertType(*result, *resultType); + std::optional 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 left = evaluate(_operation.leftExpression()); - optional right = evaluate(_operation.rightExpression()); + std::optional left = evaluate(_operation.leftExpression()); + std::optional 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 value = evaluateBinaryOperator(_operation.getOperator(), left->value, right->value)) + if (std::optional value = evaluateBinaryOperator(_operation.getOperator(), left->value, right->value)) { - optional convertedValue = convertType(*value, *resultType); + std::optional convertedValue = convertType(*value, *resultType); if (!convertedValue) m_errorReporter.fatalTypeError( 2643_error, diff --git a/libsolidity/analysis/ContractLevelChecker.cpp b/libsolidity/analysis/ContractLevelChecker.cpp index e7e7041a0ff1..eaeaf4851710 100644 --- a/libsolidity/analysis/ContractLevelChecker.cpp +++ b/libsolidity/analysis/ContractLevelChecker.cpp @@ -32,7 +32,6 @@ #include -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 -map> filterDeclarations( - map> const& _declarations) +std::map> filterDeclarations( + std::map> const& _declarations) { - map> filteredDeclarations; + std::map> filteredDeclarations; for (auto const& [name, overloads]: _declarations) for (auto const* declaration: overloads) if (auto typedDeclaration = dynamic_cast(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> functions; + std::map> 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> events; + std::map> 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 -void ContractLevelChecker::findDuplicateDefinitions(map> const& _definitions) +void ContractLevelChecker::findDuplicateDefinitions(std::map> const& _definitions) { for (auto const& it: _definitions) { - vector const& overloads = it.second; - set reported; + std::vector const& overloads = it.second; + std::set reported; for (size_t i = 0; i < overloads.size() && !reported.count(i); ++i) { SecondarySourceLocation ssl; @@ -228,15 +227,15 @@ void ContractLevelChecker::findDuplicateDefinitions(map> const if (ssl.infos.size() > 0) { ErrorId error; - string message; - if constexpr (is_same_v) + std::string message; + if constexpr (std::is_same_v) { error = 1686_error; message = "Function with same name and parameter types defined twice."; } else { - static_assert(is_same_v, "Expected \"FunctionDefinition const*\" or \"EventDefinition const*\""); + static_assert(std::is_same_v, "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 proxies; + std::set proxies; auto registerProxy = [&proxies](OverrideProxy const& _overrideProxy) { @@ -323,7 +322,7 @@ void ContractLevelChecker::checkAbstractDefinitions(ContractDefinition const& _c void ContractLevelChecker::checkBaseConstructorArguments(ContractDefinition const& _contract) { - vector const& bases = _contract.annotation().linearizedBaseContracts; + std::vector 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>> externalDeclarations; + std::map>> 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> hashes; + std::set> 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); } diff --git a/libsolidity/analysis/ControlFlowAnalyzer.cpp b/libsolidity/analysis/ControlFlowAnalyzer.cpp index e80964acebab..7ae1aa76e2b9 100644 --- a/libsolidity/analysis/ControlFlowAnalyzer.cpp +++ b/libsolidity/analysis/ControlFlowAnalyzer.cpp @@ -25,7 +25,6 @@ #include -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 mostDerivedContractName; + std::optional 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 _contractName) +void ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNode const* _exit, bool _emptyBody, std::optional _contractName) { struct NodeInfo { - set unassignedVariablesAtEntry; - set unassignedVariablesAtExit; - set uninitializedVariableAccesses; + std::set unassignedVariablesAtEntry; + std::set unassignedVariablesAtExit; + std::set 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 nodeInfos; - set nodesToTraverse; + std::map nodeInfos; + std::set 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 uninitializedAccessesOrdered( + std::vector 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." diff --git a/libsolidity/analysis/ControlFlowBuilder.cpp b/libsolidity/analysis/ControlFlowBuilder.cpp index 1f2cfcac9dd5..c20968a14d79 100644 --- a/libsolidity/analysis/ControlFlowBuilder.cpp +++ b/libsolidity/analysis/ControlFlowBuilder.cpp @@ -21,10 +21,8 @@ #include #include -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 ControlFlowBuilder::createFunctionFlow( +std::unique_ptr ControlFlowBuilder::createFunctionFlow( CFG::NodeContainer& _nodeContainer, FunctionDefinition const& _function, ContractDefinition const* _contract ) { - auto functionFlow = make_unique(); + auto functionFlow = std::make_unique(); functionFlow->entry = _nodeContainer.newNode(); functionFlow->exit = _nodeContainer.newNode(); functionFlow->revert = _nodeContainer.newNode(); diff --git a/libsolidity/analysis/ControlFlowGraph.cpp b/libsolidity/analysis/ControlFlowGraph.cpp index 71acb8a672f0..518743ef1993 100644 --- a/libsolidity/analysis/ControlFlowGraph.cpp +++ b/libsolidity/analysis/ControlFlowGraph.cpp @@ -20,7 +20,6 @@ #include -using namespace std; using namespace solidity::langutil; using namespace solidity::frontend; diff --git a/libsolidity/analysis/DeclarationContainer.cpp b/libsolidity/analysis/DeclarationContainer.cpp index b6cd3eef01ba..df6e664baca1 100644 --- a/libsolidity/analysis/DeclarationContainer.cpp +++ b/libsolidity/analysis/DeclarationContainer.cpp @@ -29,7 +29,6 @@ #include #include -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 declarations; + std::vector 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& decls = _invisible ? m_invisibleDeclarations[*_name] : m_declarations[*_name]; + std::vector& 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 DeclarationContainer::resolveName( +std::vector DeclarationContainer::resolveName( ASTString const& _name, ResolvingSettings _settings ) const { solAssert(!_name.empty(), "Attempt to resolve empty name."); - vector result; + std::vector result; if (m_declarations.count(_name)) { @@ -172,24 +171,24 @@ vector DeclarationContainer::resolveName( return result; } -vector DeclarationContainer::similarNames(ASTString const& _name) const +std::vector 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 similar; + std::vector 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 DeclarationContainer::similarNames(ASTString const& _name) con return similar; } -void DeclarationContainer::populateHomonyms(back_insert_iterator _it) const +void DeclarationContainer::populateHomonyms(std::back_insert_iterator _it) const { for (DeclarationContainer const* innerContainer: m_innerContainers) innerContainer->populateHomonyms(_it); @@ -210,7 +209,7 @@ void DeclarationContainer::populateHomonyms(back_insert_iterator _it) ResolvingSettings settings; settings.recursive = true; settings.alsoInvisible = true; - vector const& declarations = m_enclosingContainer->resolveName(name, std::move(settings)); + std::vector const& declarations = m_enclosingContainer->resolveName(name, std::move(settings)); if (!declarations.empty()) _it = make_pair(location, declarations); } diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index f17c854a7bff..28c051c0a000 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -29,7 +29,6 @@ #include -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 lengthValue; + std::optional lengthValue; if (length->annotation().type && length->annotation().type->category() == Type::Category::RationalNumber) lengthValue = dynamic_cast(*length->annotation().type).value(); - else if (optional value = ConstantEvaluator::evaluate(m_errorReporter, *length)) + else if (std::optional 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 allowedDataLocations = _variable.allowedDataLocations(); + std::set 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"; diff --git a/libsolidity/analysis/DocStringAnalyser.cpp b/libsolidity/analysis/DocStringAnalyser.cpp index 5cff34f2a0ae..d4afadf26f5d 100644 --- a/libsolidity/analysis/DocStringAnalyser.cpp +++ b/libsolidity/analysis/DocStringAnalyser.cpp @@ -30,7 +30,6 @@ #include -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 const& _baseFunctions, StructurallyDocumentedAnnotation& _target, FunctionType const* _functionType = nullptr) +void copyMissingTags(std::set 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 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 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 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 const& _baseFunctions, Stru } } -CallableDeclaration const* findBaseCallable(set const& _baseFunctions, int64_t _contractId) +CallableDeclaration const* findBaseCallable(std::set 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 const& _baseFuncs, + std::set const& _baseFuncs, StructurallyDocumented const& _node, StructurallyDocumentedAnnotation& _annotation ) diff --git a/libsolidity/analysis/DocStringTagParser.cpp b/libsolidity/analysis/DocStringTagParser.cpp index 1dc2711ef1d3..5d95f42e902c 100644 --- a/libsolidity/analysis/DocStringTagParser.cpp +++ b/libsolidity/analysis/DocStringTagParser.cpp @@ -37,7 +37,6 @@ #include #include -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 returnParameterNames; + std::vector returnParameterNames; if (auto const* varDecl = dynamic_cast(&_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 const validTags = set{"author", "title", "dev", "notice"}; + static std::set const validTags = std::set{"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 values; + std::vector values; boost::split(values, tagValue.content, isWhiteSpace); - set valuesSeen; - set duplicates; - for (auto const& value: values | ranges::views::filter(not_fn(&string::empty))) + std::set valuesSeen; + std::set 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 validParams; + std::set 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 const validTags = set{"author", "dev", "notice", "param"}; + static std::set const validTags = std::set{"author", "dev", "notice", "param"}; parseDocStrings(_node, _annotation, validTags, "constructor"); checkParameters(_callable, _node, _annotation); } @@ -279,10 +278,10 @@ void DocStringTagParser::handleCallable( StructurallyDocumentedAnnotation& _annotation ) { - static set const validEventTags = set{"dev", "notice", "return", "param"}; - static set const validErrorTags = set{"dev", "notice", "param"}; - static set const validModifierTags = set{"dev", "notice", "param", "inheritdoc"}; - static set const validTags = set{"dev", "notice", "return", "param", "inheritdoc"}; + static std::set const validEventTags = std::set{"dev", "notice", "return", "param"}; + static std::set const validErrorTags = std::set{"dev", "notice", "param"}; + static std::set const validModifierTags = std::set{"dev", "notice", "param", "inheritdoc"}; + static std::set const validTags = std::set{"dev", "notice", "return", "param", "inheritdoc"}; if (dynamic_cast(&_callable)) parseDocStrings(_node, _annotation, validEventTags, "events"); @@ -299,8 +298,8 @@ void DocStringTagParser::handleCallable( void DocStringTagParser::parseDocStrings( StructurallyDocumented const& _node, StructurallyDocumentedAnnotation& _annotation, - set const& _validTags, - string const& _nodeName + std::set 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, diff --git a/libsolidity/analysis/FunctionCallGraph.cpp b/libsolidity/analysis/FunctionCallGraph.cpp index ce5c539346b5..1d01f1a6bced 100644 --- a/libsolidity/analysis/FunctionCallGraph.cpp +++ b/libsolidity/analysis/FunctionCallGraph.cpp @@ -24,7 +24,6 @@ #include #include -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 defaultNode; + std::set defaultNode; for (CallGraph::Node const& dispatchTarget: util::valueOrDefault(_creationGraph.edges, CallGraph::SpecialNode::InternalDispatch, defaultNode)) { - solAssert(!holds_alternative(dispatchTarget), ""); - solAssert(get(dispatchTarget) != nullptr, ""); + solAssert(!std::holds_alternative(dispatchTarget), ""); + solAssert(std::get(dispatchTarget) != nullptr, ""); // Visit the callable to add not only it but also everything it calls too - builder.functionReferenced(*get(dispatchTarget), false); + builder.functionReferenced(*std::get(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(m_currentNode), ""); + solAssert(std::holds_alternative(m_currentNode), ""); m_visitQueue.pop_front(); - get(m_currentNode)->accept(*this); + std::get(m_currentNode)->accept(*this); } m_currentNode = CallGraph::SpecialNode::Entry; @@ -281,7 +280,7 @@ void FunctionCallGraphBuilder::functionReferenced(CallableDeclaration const& _ca if (_calledDirectly) { solAssert( - holds_alternative(m_currentNode) || m_graph.edges.count(m_currentNode) > 0, + std::holds_alternative(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(_node)) - switch (get(_node)) + if (std::holds_alternative(_node)) + switch (std::get(_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(_node), ""); + solAssert(std::holds_alternative(_node), ""); - auto const* callableDeclaration = get(_node); + auto const* callableDeclaration = std::get(_node); solAssert(callableDeclaration, ""); auto const* function = dynamic_cast(callableDeclaration); auto const* event = dynamic_cast(callableDeclaration); auto const* modifier = dynamic_cast(callableDeclaration); - auto typeToString = [](auto const& _var) -> string { return _var->type()->toString(true); }; - vector parameters = callableDeclaration->parameters() | ranges::views::transform(typeToString) | ranges::to>(); + auto typeToString = [](auto const& _var) -> std::string { return _var->type()->toString(true); }; + std::vector parameters = callableDeclaration->parameters() | ranges::views::transform(typeToString) | ranges::to>(); - string scopeName; + std::string scopeName; if (!function || !function->isFree()) { solAssert(callableDeclaration->annotation().scope, ""); diff --git a/libsolidity/analysis/GlobalContext.cpp b/libsolidity/analysis/GlobalContext.cpp index 5a8409fa12d6..a21a38a2e129 100644 --- a/libsolidity/analysis/GlobalContext.cpp +++ b/libsolidity/analysis/GlobalContext.cpp @@ -29,8 +29,6 @@ #include #include -using namespace std; - namespace solidity::frontend { @@ -88,10 +86,10 @@ int magicVariableToID(std::string const& _name) solAssert(false, "Unknown magic variable: \"" + _name + "\"."); } -inline vector> constructMagicVariables() +inline std::vector> constructMagicVariables() { - static auto const magicVarDecl = [](string const& _name, Type const* _type) { - return make_shared(magicVariableToID(_name), _name, _type); + static auto const magicVarDecl = [](std::string const& _name, Type const* _type) { + return std::make_shared(magicVariableToID(_name), _name, _type); }; return { @@ -185,7 +183,7 @@ void GlobalContext::addVerifyMintProofMethod() { strings returnParameterNames; returnParameterNames.push_back("msg"); - m_magicVariables.push_back(make_shared(magicVariableToID("verifyMintProof"), "verifyMintProof", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("verifyMintProof"), "verifyMintProof", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -223,7 +221,7 @@ void GlobalContext::addVerifyBurnProofMethod() { strings returnParameterNames; returnParameterNames.push_back("msg"); - m_magicVariables.push_back(make_shared(magicVariableToID("verifyBurnProof"), "verifyBurnProof", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("verifyBurnProof"), "verifyBurnProof", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -275,7 +273,7 @@ void GlobalContext::addVerifyTransferProofMethod() { strings returnParameterNames; returnParameterNames.push_back("msg"); - m_magicVariables.push_back(make_shared(magicVariableToID("verifyTransferProof"), "verifyTransferProof", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("verifyTransferProof"), "verifyTransferProof", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -307,7 +305,7 @@ void GlobalContext::addPedersenHashMethod() { strings returnParameterNames; returnParameterNames.push_back("msg"); - m_magicVariables.push_back(make_shared(magicVariableToID("pedersenHash"), "pedersenHash", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("pedersenHash"), "pedersenHash", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -335,7 +333,7 @@ void GlobalContext::addBatchValidateSignMethod() { strings returnParameterNames; returnParameterNames.push_back("ok"); - m_magicVariables.push_back(make_shared(magicVariableToID("batchvalidatesign"), "batchvalidatesign", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("batchvalidatesign"), "batchvalidatesign", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -365,7 +363,7 @@ void GlobalContext::addValidateMultiSignMethod() { strings returnParameterNames; returnParameterNames.push_back("ok"); - m_magicVariables.push_back(make_shared(magicVariableToID("validatemultisign"), "validatemultisign", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("validatemultisign"), "validatemultisign", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -389,7 +387,7 @@ void GlobalContext::addVoteMethod() { parameterNames.push_back("tronpowerList"); strings returnParameterNames; - m_magicVariables.push_back(make_shared(magicVariableToID("vote"), "vote", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("vote"), "vote", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -409,7 +407,7 @@ void GlobalContext::addRewardBalanceMethod() { strings returnParameterNames; returnParameterNames.push_back("result"); - m_magicVariables.push_back(make_shared(magicVariableToID("rewardBalance"), "rewardBalance", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("rewardBalance"), "rewardBalance", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -432,7 +430,7 @@ void GlobalContext::addIsSRCandidateMethod() { strings returnParameterNames; returnParameterNames.push_back("ok"); - m_magicVariables.push_back(make_shared(magicVariableToID("isSrCandidate"), "isSrCandidate", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("isSrCandidate"), "isSrCandidate", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -457,7 +455,7 @@ void GlobalContext::addVoteCountMethod() { strings returnParameterNames; returnParameterNames.push_back("result"); - m_magicVariables.push_back(make_shared(magicVariableToID("voteCount"), "voteCount", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("voteCount"), "voteCount", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -480,7 +478,7 @@ void GlobalContext::addTotalVoteCountMethod() { strings returnParameterNames; returnParameterNames.push_back("result"); - m_magicVariables.push_back(make_shared(magicVariableToID("totalVoteCount"), "totalVoteCount", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("totalVoteCount"), "totalVoteCount", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -503,7 +501,7 @@ void GlobalContext::addReceivedVoteCountMethod() { strings returnParameterNames; returnParameterNames.push_back("result"); - m_magicVariables.push_back(make_shared(magicVariableToID("receivedVoteCount"), "receivedVoteCount", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("receivedVoteCount"), "receivedVoteCount", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -526,7 +524,7 @@ void GlobalContext::addUsedVoteCountMethod() { strings returnParameterNames; returnParameterNames.push_back("result"); - m_magicVariables.push_back(make_shared(magicVariableToID("usedVoteCount"), "usedVoteCount", TypeProvider::function( + m_magicVariables.push_back(std::make_shared(magicVariableToID("usedVoteCount"), "usedVoteCount", TypeProvider::function( parameterTypes, returnParameterTypes, parameterNames, @@ -542,9 +540,9 @@ void GlobalContext::setCurrentContract(ContractDefinition const& _contract) m_currentContract = &_contract; } -vector GlobalContext::declarations() const +std::vector GlobalContext::declarations() const { - vector declarations; + std::vector declarations; declarations.reserve(m_magicVariables.size()); for (ASTPointer const& variable: m_magicVariables) declarations.push_back(variable.get()); @@ -559,7 +557,7 @@ MagicVariableDeclaration const* GlobalContext::currentThis() const if (m_currentContract) type = TypeProvider::contract(*m_currentContract); m_thisPointer[m_currentContract] = - make_shared(magicVariableToID("this"), "this", type); + std::make_shared(magicVariableToID("this"), "this", type); } return m_thisPointer[m_currentContract].get(); } @@ -572,7 +570,7 @@ MagicVariableDeclaration const* GlobalContext::currentSuper() const if (m_currentContract) type = TypeProvider::typeType(TypeProvider::contract(*m_currentContract, true)); m_superPointer[m_currentContract] = - make_shared(magicVariableToID("super"), "super", type); + std::make_shared(magicVariableToID("super"), "super", type); } return m_superPointer[m_currentContract].get(); } diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 641f02280430..d6ff63dbf34f 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -30,7 +30,6 @@ #include #include -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(); + m_scopes[nullptr] = std::make_shared(); 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 const& _sourceUnits) +bool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, std::map const& _sourceUnits) { DeclarationContainer& target = *m_scopes.at(&_sourceUnit); bool error = false; for (auto const& node: _sourceUnit.nodes()) if (auto imp = dynamic_cast(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 const& node: _source.nodes()) + for (std::shared_ptr 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 NameAndTypeResolver::resolveName(ASTString const& _name, ASTNode const* _scope) const +std::vector NameAndTypeResolver::resolveName(ASTString const& _name, ASTNode const* _scope) const { auto iterator = m_scopes.find(_scope); if (iterator == end(m_scopes)) - return vector({}); + return std::vector({}); return iterator->second->resolveName(_name); } -vector NameAndTypeResolver::nameFromCurrentScope(ASTString const& _name, bool _includeInvisibles) const +std::vector NameAndTypeResolver::nameFromCurrentScope(ASTString const& _name, bool _includeInvisibles) const { ResolvingSettings settings; settings.recursive = true; @@ -187,7 +186,7 @@ vector NameAndTypeResolver::nameFromCurrentScope(ASTString c return m_currentScope->resolveName(_name, std::move(settings)); } -Declaration const* NameAndTypeResolver::pathFromCurrentScope(vector const& _path) const +Declaration const* NameAndTypeResolver::pathFromCurrentScope(std::vector const& _path) const { if (auto declarations = pathFromCurrentScopeWithAllDeclarations(_path); !declarations.empty()) return declarations.back(); @@ -201,13 +200,13 @@ std::vector NameAndTypeResolver::pathFromCurrentScopeWithAll ) const { solAssert(!_path.empty(), ""); - vector pathDeclarations; + std::vector pathDeclarations; ResolvingSettings settings; settings.recursive = true; settings.alsoInvisible = _includeInvisibles; settings.onlyVisibleAsUnqualifiedNames = true; - vector candidates = m_currentScope->resolveName(_path.front(), settings); + std::vector 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 properBases( + std::vector 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> input(1, list{}); + std::list> input(1, std::list{}); for (ASTPointer 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 const& basesBases = base->annotation().linearizedBaseContracts; + std::vector 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(basesBases.begin(), basesBases.end())); + input.push_front(std::list(basesBases.begin(), basesBases.end())); } input.back().push_front(&_contract); - vector result = cThreeMerge(input); + std::vector result = cThreeMerge(input); if (result.empty()) m_errorReporter.fatalTypeError(5005_error, _contract.location(), "Linearization of inheritance graph impossible"); _contract.annotation().linearizedBaseContracts = result; } template -vector NameAndTypeResolver::cThreeMerge(list>& _toMerge) +std::vector NameAndTypeResolver::cThreeMerge(std::list>& _toMerge) { // returns true iff _candidate appears only as last element of the lists auto appearsOnlyAtHead = [&](T const* _candidate) -> bool { - for (list const& bases: _toMerge) + for (std::list const& bases: _toMerge) { solAssert(!bases.empty(), ""); if (find(++bases.begin(), bases.end(), _candidate) != bases.end()) @@ -444,7 +443,7 @@ vector NameAndTypeResolver::cThreeMerge(list>& _toMerge // returns the next candidate to append to the linearized list or nullptr on failure auto nextCandidate = [&]() -> T const* { - for (list const& bases: _toMerge) + for (std::list const& bases: _toMerge) { solAssert(!bases.empty(), ""); if (appearsOnlyAtHead(bases.front())) @@ -465,26 +464,26 @@ vector NameAndTypeResolver::cThreeMerge(list>& _toMerge } }; - _toMerge.remove_if([](list const& _bases) { return _bases.empty(); }); - vector result; + _toMerge.remove_if([](std::list const& _bases) { return _bases.empty(); }); + std::vector result; while (!_toMerge.empty()) { T const* candidate = nextCandidate(); if (!candidate) - return vector(); + return std::vector(); 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>& _scopes, + std::map>& _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 illegalNames{"_", "super", "this"}; + static std::set 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(m_currentScope, m_scopes[m_currentScope].get()); + m_scopes[&_sourceUnit] = std::make_shared(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(nullptr, m_scopes[nullptr].get()); + m_scopes[importee] = std::make_shared(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(&_node.annotation())) { - string canonicalName = dynamic_cast(_node).name(); + std::string canonicalName = dynamic_cast(_node).name(); solAssert(!canonicalName.empty(), ""); for ( @@ -684,7 +683,7 @@ void DeclarationRegistrationHelper::enterNewSubScope(ASTNode& _subScope) { bool newlyAdded = m_scopes.emplace( &_subScope, - make_shared(m_currentScope, m_scopes[m_currentScope].get()) + std::make_shared(m_currentScope, m_scopes[m_currentScope].get()) ).second; solAssert(newlyAdded, "Unable to add new scope."); } diff --git a/libsolidity/analysis/OverrideChecker.cpp b/libsolidity/analysis/OverrideChecker.cpp index d342ab100359..f2a99340deee 100644 --- a/libsolidity/analysis/OverrideChecker.cpp +++ b/libsolidity/analysis/OverrideChecker.cpp @@ -31,7 +31,6 @@ #include -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 const& _baseCallables) + OverrideGraph(std::set const& _baseCallables) { for (auto const& baseFunction: _baseCallables) addEdge(0, visit(baseFunction)); @@ -131,17 +130,17 @@ struct CutVertexFinder run(vInd, _depth + 1); if (m_low[vInd] >= m_depths[_u] && m_parent[_u] != -1) m_cutVertices.insert(m_graph.nodeInv.at(static_cast(_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 resolveDirectBaseContracts(ContractDefinition const& _contract) +std::vector resolveDirectBaseContracts(ContractDefinition const& _contract) { - vector resolvedContracts; + std::vector resolvedContracts; for (ASTPointer const& specifier: _contract.baseContracts()) { @@ -155,7 +154,7 @@ vector resolveDirectBaseContracts(ContractDefinition return resolvedContracts; } -vector> sortByContract(vector> const& _list) +std::vector> sortByContract(std::vector> const& _list) { auto sorted = _list; @@ -197,17 +196,17 @@ bool OverrideProxy::operator<(OverrideProxy const& _other) const bool OverrideProxy::isVariable() const { - return holds_alternative(m_item); + return std::holds_alternative(m_item); } bool OverrideProxy::isFunction() const { - return holds_alternative(m_item); + return std::holds_alternative(m_item); } bool OverrideProxy::isModifier() const { - return holds_alternative(m_item); + return std::holds_alternative(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 OverrideProxy::overrides() const +std::shared_ptr OverrideProxy::overrides() const { return std::visit(GenericVisitor{ [&](auto const* _item) { return _item->overrides(); } }, m_item); } -set OverrideProxy::baseFunctions() const +std::set OverrideProxy::baseFunctions() const { return std::visit(GenericVisitor{ - [&](auto const* _item) -> set { - set ret; + [&](auto const* _item) -> std::set { + std::set 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(std::visit(GenericVisitor{ + m_comparator = std::make_shared(std::visit(GenericVisitor{ [&](FunctionDefinition const* _function) { - vector paramTypes; + std::vector 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 paramTypes; + std::vector 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 _secondary, + std::set _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 names; + std::set 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 const& _secondaryMsg + std::string const& _message, + std::optional const& _secondaryMsg ) { m_errorReporter.typeError( @@ -766,7 +765,7 @@ void OverrideChecker::checkAmbiguousOverrides(ContractDefinition const& _contrac } } -void OverrideChecker::checkAmbiguousOverridesInternal(set _baseCallables, SourceLocation const& _location) const +void OverrideChecker::checkAmbiguousOverridesInternal(std::set _baseCallables, SourceLocation const& _location) const { if (_baseCallables.size() <= 1) return; @@ -799,17 +798,17 @@ void OverrideChecker::checkAmbiguousOverridesInternal(set _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 _baseCa m_errorReporter.typeError(6480_error, _location, ssl, message); } -set OverrideChecker::resolveOverrideList(OverrideSpecifier const& _overrides) const +std::set OverrideChecker::resolveOverrideList(OverrideSpecifier const& _overrides) const { - set resolved; + std::set resolved; for (ASTPointer const& override: _overrides.overrides()) { @@ -842,7 +841,7 @@ set OverrideChecker::re void OverrideChecker::checkOverrideList(OverrideProxy _item, OverrideProxyBySignatureMultiSet const& _inherited) { - set specifiedContracts = + std::set 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> list = + std::vector> list = sortByContract(_item.overrides()->overrides()); // Find duplicates and output error @@ -880,7 +879,7 @@ void OverrideChecker::checkOverrideList(OverrideProxy _item, OverrideProxyBySign } } - set expectedContracts; + std::set 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 missingContracts; + std::set 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 functionsInBase; + std::set 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 modifiersInBase; + std::set modifiersInBase; for (ModifierDefinition const* mod: base->functionModifiers()) modifiersInBase.emplace(OverrideProxy{mod}); diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp index c8b3b5f162b2..fe3a59d0cc97 100644 --- a/libsolidity/analysis/PostTypeChecker.cpp +++ b/libsolidity/analysis/PostTypeChecker.cpp @@ -24,10 +24,13 @@ #include #include #include +#include +#include + +#include #include -using namespace std; using namespace solidity; using namespace solidity::langutil; using namespace solidity::frontend; @@ -130,6 +133,17 @@ void PostTypeChecker::endVisit(ModifierInvocation const& _modifierInvocation) callEndVisit(_modifierInvocation); } + +bool PostTypeChecker::visit(ForStatement const& _forStatement) +{ + return callVisit(_forStatement); +} + +void PostTypeChecker::endVisit(ForStatement const& _forStatement) +{ + callEndVisit(_forStatement); +} + namespace { struct ConstStateVarCircularReferenceChecker: public PostTypeChecker::Checker @@ -204,7 +218,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 dependencies( + std::vector dependencies( m_constVariableDependencies[&_variable].begin(), m_constVariableDependencies[&_variable].end() ); @@ -422,15 +436,126 @@ struct ReservedErrorSelector: public PostTypeChecker::Checker } }; +class YulLValueChecker : public solidity::yul::ASTWalker +{ +public: + YulLValueChecker(ASTString const& _identifierName): m_identifierName(_identifierName) {} + bool willBeWrittenTo() const { return m_willBeWrittenTo; } + using solidity::yul::ASTWalker::operator(); + void operator()(solidity::yul::Assignment const& _assignment) override + { + if (m_willBeWrittenTo) + return; + + if (ranges::any_of( + _assignment.variableNames, + [&](auto const& yulIdentifier) { return yulIdentifier.name.str() == m_identifierName; } + )) + m_willBeWrittenTo = true; + } +private: + ASTString const& m_identifierName; + bool m_willBeWrittenTo = false; +}; + +class LValueChecker: public ASTConstVisitor +{ +public: + LValueChecker(Identifier const& _identifier): + m_declaration(_identifier.annotation().referencedDeclaration) + {} + bool willBeWrittenTo() const { return m_willBeWrittenTo; } + void endVisit(Identifier const& _identifier) override + { + if (m_willBeWrittenTo) + return; + + solAssert(_identifier.annotation().referencedDeclaration); + if ( + *_identifier.annotation().referencedDeclaration == *m_declaration && + _identifier.annotation().willBeWrittenTo + ) + m_willBeWrittenTo = true; + } + void endVisit(InlineAssembly const& _inlineAssembly) override + { + if (m_willBeWrittenTo) + return; + + YulLValueChecker yulChecker{m_declaration->name()}; + yulChecker(_inlineAssembly.operations()); + m_willBeWrittenTo = yulChecker.willBeWrittenTo(); + } +private: + Declaration const* m_declaration{}; + bool m_willBeWrittenTo = false; +}; + +struct SimpleCounterForLoopChecker: public PostTypeChecker::Checker +{ + SimpleCounterForLoopChecker(ErrorReporter& _errorReporter): Checker(_errorReporter) {} + bool visit(ForStatement const& _forStatement) override + { + _forStatement.annotation().isSimpleCounterLoop = isSimpleCounterLoop(_forStatement); + return true; + } + bool isSimpleCounterLoop(ForStatement const& _forStatement) const + { + auto const* simpleCondition = dynamic_cast(_forStatement.condition()); + if (!simpleCondition || simpleCondition->getOperator() != Token::LessThan || simpleCondition->userDefinedFunctionType()) + return false; + if (!_forStatement.loopExpression()) + return false; + + auto const* simplePostExpression = dynamic_cast(&_forStatement.loopExpression()->expression()); + // This matches both operators ++i and i++ + if (!simplePostExpression || simplePostExpression->getOperator() != Token::Inc || simplePostExpression->userDefinedFunctionType()) + return false; + + auto const* lhsIdentifier = dynamic_cast(&simpleCondition->leftExpression()); + auto const* lhsIntegerType = dynamic_cast(simpleCondition->leftExpression().annotation().type); + auto const* commonIntegerType = dynamic_cast(simpleCondition->annotation().commonType); + + if (!lhsIdentifier || !lhsIntegerType || !commonIntegerType || *lhsIntegerType != *commonIntegerType) + return false; + + auto const* incExpressionIdentifier = dynamic_cast(&simplePostExpression->subExpression()); + if ( + !incExpressionIdentifier || + incExpressionIdentifier->annotation().referencedDeclaration != lhsIdentifier->annotation().referencedDeclaration + ) + return false; + + solAssert(incExpressionIdentifier->annotation().referencedDeclaration); + if ( + auto const* incVariableDeclaration = dynamic_cast( + incExpressionIdentifier->annotation().referencedDeclaration + ); + incVariableDeclaration && + !incVariableDeclaration->isLocalVariable() + ) + return false; + + solAssert(lhsIdentifier); + LValueChecker lValueChecker{*lhsIdentifier}; + simpleCondition->rightExpression().accept(lValueChecker); + if (!lValueChecker.willBeWrittenTo()) + _forStatement.body().accept(lValueChecker); + + return !lValueChecker.willBeWrittenTo(); + } +}; + } PostTypeChecker::PostTypeChecker(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) { - m_checkers.push_back(make_shared(_errorReporter)); - m_checkers.push_back(make_shared(_errorReporter)); - m_checkers.push_back(make_shared(_errorReporter)); - m_checkers.push_back(make_shared(_errorReporter)); - m_checkers.push_back(make_shared(_errorReporter)); - m_checkers.push_back(make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); } diff --git a/libsolidity/analysis/PostTypeChecker.h b/libsolidity/analysis/PostTypeChecker.h index 04b4fbe7a29e..178130a35663 100644 --- a/libsolidity/analysis/PostTypeChecker.h +++ b/libsolidity/analysis/PostTypeChecker.h @@ -97,6 +97,9 @@ class PostTypeChecker: private ASTConstVisitor bool visit(ModifierInvocation const& _modifierInvocation) override; void endVisit(ModifierInvocation const& _modifierInvocation) override; + bool visit(ForStatement const& _forStatement) override; + void endVisit(ForStatement const& _forStatement) override; + template bool callVisit(T const& _node) { diff --git a/libsolidity/analysis/PostTypeContractLevelChecker.cpp b/libsolidity/analysis/PostTypeContractLevelChecker.cpp index 67d0623aa04f..6d8dc416aa00 100644 --- a/libsolidity/analysis/PostTypeContractLevelChecker.cpp +++ b/libsolidity/analysis/PostTypeContractLevelChecker.cpp @@ -26,7 +26,6 @@ #include #include -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> errorHashes; + std::map> 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)) diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index 399c15b56e36..e680021331a2 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -39,7 +39,6 @@ #include #include -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 declarations = m_resolver.pathFromCurrentScopeWithAllDeclarations(path->path(), true /* _includeInvisibles */); + std::vector 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 suffixes{"slot", "offset", "length", "address", "selector"}; - string suffix; - for (string const& s: suffixes) + static std::set 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 path; + std::vector 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{"this", "super", "_"}.count(_name.str())) + if (std::set{"this", "super", "_"}.count(_name.str())) m_errorReporter.declarationError( 4113_error, _location, diff --git a/libsolidity/analysis/Scoper.cpp b/libsolidity/analysis/Scoper.cpp index 98716cf0f867..a14ca4559751 100644 --- a/libsolidity/analysis/Scoper.cpp +++ b/libsolidity/analysis/Scoper.cpp @@ -20,7 +20,6 @@ #include -using namespace std; using namespace solidity; using namespace solidity::frontend; diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 01ca601f1222..10c2c922ca47 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -28,7 +28,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::langutil; using namespace solidity::frontend; @@ -71,7 +70,7 @@ class solidity::frontend::ConstructorUsesAssembly return m_usesAssembly[&_contract]; } - map m_usesAssembly; + std::map 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(); + m_constructorUsesAssembly = std::make_unique(); ContractType const& contract = dynamic_cast(*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; } } diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index 4f99f67ac623..b2dd73cc244c 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -32,7 +32,6 @@ #include -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 literals(_pragma.literals().begin() + 1, _pragma.literals().end()); + std::vector 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{"v1", "v2"}.count(_pragma.literals()[1]) + !std::set{"v1", "v2"}.count(_pragma.literals()[1]) ) m_errorReporter.syntaxError( 2745_error, @@ -155,19 +154,12 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma) { try { - vector tokens(_pragma.tokens().begin() + 1, _pragma.tokens().end()); - vector literals(_pragma.literals().begin() + 1, _pragma.literals().end()); + std::vector tokens(_pragma.tokens().begin() + 1, _pragma.tokens().end()); + std::vector 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 diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 03513e814913..072e27080d15 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -51,7 +51,6 @@ #include #include -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> arguments = _functionCall.arguments(); + std::vector> 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> arguments = _functionCall.arguments(); + std::vector> 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 internalParametersInConstructor; + std::vector 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 modifiers; + std::set modifiers; for (ASTPointer const& modifier: _function.modifiers()) { - vector baseContracts; + std::vector baseContracts; if (auto contract = dynamic_cast(_function.scope())) { baseContracts = contract->annotation().linearizedBaseContracts; @@ -522,7 +521,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function) visitManually( *modifier, - _function.isConstructor() ? baseContracts : vector() + _function.isConstructor() ? baseContracts : std::vector() ); 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 unsupportedTypes; + std::vector 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 const& _bases + std::vector const& _bases ) { std::vector> const& arguments = @@ -724,8 +723,8 @@ void TypeChecker::visitManually( _modifier.name().accept(*this); auto const* declaration = &dereference(_modifier.name()); - vector> emptyParameterList; - vector> const* parameters = nullptr; + std::vector> emptyParameterList; + std::vector> const* parameters = nullptr; if (auto modifierDecl = dynamic_cast(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{"offset", "slot", "length", "selector", "address"}).count(suffix), ""); + std::string const& suffix = identifierInfo.suffix; + solAssert((std::set{"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(); + _inlineAssembly.annotation().analysisInfo = std::make_shared(); 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> const& variables = _statement.declarations(); + std::vector> 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(&_type); - auto const& types = tupleType && tupleExpression->components().size() != 1 ? tupleType->components() : vector { &_type }; + auto const& types = tupleType && tupleExpression->components().size() != 1 ? tupleType->components() : std::vector { &_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> const& components = _tuple.components(); + std::vector> 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 matchingDefinitions = operandType->operatorDefinitions( + std::set 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 matchingDefinitions = leftType->operatorDefinitions( + std::set 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> const& arguments = _functionCall.arguments(); + std::vector> const& arguments = _functionCall.arguments(); bool const isPositionalCall = _functionCall.names().empty(); Type const* resultType = dynamic_cast(*expressionType).actualType(); @@ -2215,7 +2214,7 @@ void TypeChecker::typeCheckABIEncodeFunctions( } // Check additional arguments for variadic functions - vector> const& arguments = _functionCall.arguments(); + std::vector> 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> const& arguments = _functionCall.arguments(); + std::vector> 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> callArguments; + std::vector> callArguments; auto const* tupleType = dynamic_cast(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 const& argument: _functionCall.arguments()) + for (std::shared_ptr 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 const& argument: _functionCall.arguments()) + for (std::shared_ptr const& argument: _functionCall.arguments()) { Type const* argumentType = type(*argument); bool notConvertibleToBytes = @@ -2504,8 +2503,8 @@ void TypeChecker::typeCheckFunctionGeneralChecks( ); TypePointers const& parameterTypes = _functionType->parameterTypes(); - vector> const& arguments = _functionCall.arguments(); - vector> const& argumentNames = _functionCall.names(); + std::vector> const& arguments = _functionCall.arguments(); + std::vector> 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 { - string msg = isVariadic ? + auto [errorId, description] = [&]() -> std::tuple { + 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 { - string msg = + auto [errorId, description] = [&]() -> std::tuple { + 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> const& arguments = _functionCall.arguments(); + std::vector> const& arguments = _functionCall.arguments(); bool argumentsArePure = true; // We need to check arguments' type first as they will be needed for overload resolution. @@ -2992,7 +2991,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( @@ -3006,7 +3005,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) @@ -3186,8 +3185,8 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) ); } - auto [errorId, description] = [&]() -> tuple { - string errorMsg = "Member \"" + memberName + "\" not found or not visible " + auto [errorId, description] = [&]() -> std::tuple { + std::string errorMsg = "Member \"" + memberName + "\" not found or not visible " "after argument-dependent lookup in " + exprType->humanReadableName() + "."; if (auto const* funType = dynamic_cast(exprType)) @@ -3223,7 +3222,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) if (addressMember.name == memberName) { auto const* var = dynamic_cast(&_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 }; } @@ -3607,13 +3606,13 @@ bool TypeChecker::visit(IndexRangeAccess const& _access) return false; } -vector TypeChecker::cleanOverloadedDeclarations( +std::vector TypeChecker::cleanOverloadedDeclarations( Identifier const& _identifier, - vector const& _candidates + std::vector const& _candidates ) { solAssert(_candidates.size() > 1, ""); - vector uniqueDeclarations; + std::vector uniqueDeclarations; for (Declaration const* declaration: _candidates) { @@ -3666,7 +3665,7 @@ bool TypeChecker::visit(Identifier const& _identifier) else if (!annotation.arguments) { // The identifier should be a public state variable shadowing other functions - vector candidates; + std::vector candidates; for (Declaration const* declaration: annotation.overloadedDeclarations) { @@ -3682,7 +3681,7 @@ bool TypeChecker::visit(Identifier const& _identifier) } else { - vector candidates; + std::vector candidates; for (Declaration const* declaration: annotation.overloadedDeclarations) { @@ -3701,7 +3700,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 + ")"; @@ -3817,12 +3816,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()) { @@ -4035,7 +4034,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 wrongParametersMessage; + std::optional 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)) @@ -4066,7 +4065,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor) TypePointers const& returnParameterTypes = functionType->returnParameterTypes(); size_t const returnParameterCount = returnParameterTypes.size(); - optional wrongReturnParametersMessage; + std::optional wrongReturnParametersMessage; if (!TokenTraits::isCompareOp(operator_.value()) && operator_.value() != Token::Not) { if (returnParameterCount != 1 || *usingForType != *returnParameterTypes.front()) @@ -4101,7 +4100,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 matchingDefinitions = usingForType->operatorDefinitions( + std::set matchingDefinitions = usingForType->operatorDefinitions( operator_.value(), *currentDefinitionScope(), parameterCount == 1 // _unary @@ -4134,7 +4133,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor) void TypeChecker::checkErrorAndEventParameters(CallableDeclaration const& _callable) { - string kind = dynamic_cast(&_callable) ? "event" : "error"; + std::string kind = dynamic_cast(&_callable) ? "event" : "error"; for (ASTPointer const& var: _callable.parameters()) { if (type(*var)->containsNestedMapping()) @@ -4224,7 +4223,7 @@ void TypeChecker::requireLValue(Expression const& _expression, bool _ordinaryAss if (*_expression.annotation().isLValue) return; - auto [errorId, description] = [&]() -> tuple { + auto [errorId, description] = [&]() -> std::tuple { if (*_expression.annotation().isConstant) return { 6520_error, "Cannot assign to a constant variable." }; diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index 2b66b0a5c923..61c5d3e6b5e1 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -27,7 +27,6 @@ #include #include -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); } @@ -386,8 +385,8 @@ void ViewPureChecker::endVisit(MemberAccess const& _memberAccess) break; case Type::Category::Magic: { - using MagicMember = pair; - set static const pureMembers{ + using MagicMember = std::pair; + std::set static const pureMembers{ {MagicType::Kind::ABI, "decode"}, {MagicType::Kind::ABI, "encode"}, {MagicType::Kind::ABI, "encodePacked"}, @@ -403,7 +402,7 @@ void ViewPureChecker::endVisit(MemberAccess const& _memberAccess) {MagicType::Kind::MetaType, "min"}, {MagicType::Kind::MetaType, "max"}, }; - set static const payableMembers{ + std::set static const payableMembers{ {MagicType::Kind::Message, "value"}, {MagicType::Kind::Message, "tokenvalue"}, {MagicType::Kind::Message, "tokenid"} diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 833ba739e146..c0bf9009186d 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -39,13 +39,12 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::frontend; namespace { -TryCatchClause const* findClause(vector> const& _clauses, optional _errorName = {}) +TryCatchClause const* findClause(std::vector> const& _clauses, std::optional _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(); + m_annotation = std::make_unique(); return *m_annotation; } @@ -128,9 +127,9 @@ SourceUnitAnnotation& SourceUnit::annotation() const return initAnnotation(); } -set SourceUnit::referencedSourceUnits(bool _recurse, set _skipList) const +std::set SourceUnit::referencedSourceUnits(bool _recurse, std::set _skipList) const { - set sourceUnits; + std::set sourceUnits; for (ImportDirective const* importDirective: filteredNodes(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, FunctionTypePointer> ContractDefinition::interfaceFunctions(bool _includeInheritedFunctions) const +std::map, FunctionTypePointer> ContractDefinition::interfaceFunctions(bool _includeInheritedFunctions) const { auto exportedFunctionList = interfaceFunctionList(_includeInheritedFunctions); - map, FunctionTypePointer> exportedFunctions; + std::map, FunctionTypePointer> exportedFunctions; for (auto const& it: exportedFunctionList) exportedFunctions.insert(it); @@ -208,11 +207,11 @@ FunctionDefinition const* ContractDefinition::receiveFunction() const return nullptr; } -vector const& ContractDefinition::definedInterfaceEvents() const +std::vector const& ContractDefinition::definedInterfaceEvents() const { return m_interfaceEvents.init([&]{ - set eventsSeen; - vector interfaceEvents; + std::set eventsSeen; + std::vector interfaceEvents; for (ContractDefinition const* contract: annotation().linearizedBaseContracts) for (EventDefinition const* e: contract->events()) @@ -222,7 +221,7 @@ vector 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 const& ContractDefinition::definedInterfaceEvents }); } -vector const ContractDefinition::usedInterfaceEvents() const +std::vector const ContractDefinition::usedInterfaceEvents() const { solAssert(annotation().creationCallGraph.set(), ""); @@ -243,9 +242,9 @@ vector const ContractDefinition::usedInterfaceEvents() c ); } -vector ContractDefinition::interfaceEvents(bool _requireCallGraph) const +std::vector ContractDefinition::interfaceEvents(bool _requireCallGraph) const { - set result; + std::set result; for (ContractDefinition const* contract: annotation().linearizedBaseContracts) result += contract->events(); solAssert(annotation().creationCallGraph.set() == annotation().deployedCallGraph.set()); @@ -255,12 +254,12 @@ vector 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>(std::move(result)); + return util::convertContainer>(std::move(result)); } -vector ContractDefinition::interfaceErrors(bool _requireCallGraph) const +std::vector ContractDefinition::interfaceErrors(bool _requireCallGraph) const { - set result; + std::set result; for (ContractDefinition const* contract: annotation().linearizedBaseContracts) result += filteredNodes(contract->m_subNodes); solAssert(annotation().creationCallGraph.set() == annotation().deployedCallGraph.set(), ""); @@ -270,20 +269,20 @@ vector ContractDefinition::interfaceErrors(bool _require result += (*annotation().creationCallGraph)->usedErrors + (*annotation().deployedCallGraph)->usedErrors; - return util::convertContainer>(std::move(result)); + return util::convertContainer>(std::move(result)); } -vector, FunctionTypePointer>> const& ContractDefinition::interfaceFunctionList(bool _includeInheritedFunctions) const +std::vector, FunctionTypePointer>> const& ContractDefinition::interfaceFunctionList(bool _includeInheritedFunctions) const { return m_interfaceFunctionList[_includeInheritedFunctions].init([&]{ - set signaturesSeen; - vector, FunctionTypePointer>> interfaceFunctionList; + std::set signaturesSeen; + std::vector, FunctionTypePointer>> interfaceFunctionList; for (ContractDefinition const* contract: annotation().linearizedBaseContracts) { if (_includeInheritedFunctions == false && contract != this) continue; - vector functions; + std::vector functions; for (FunctionDefinition const* f: contract->definedFunctions()) if (f->isPartOfExternalInterface()) functions.push_back(TypeProvider::function(*f, FunctionType::Kind::External)); @@ -295,7 +294,7 @@ vector, 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 const& ContractDefinition::definedFunctionsByName() const +std::multimap const& ContractDefinition::definedFunctionsByName() const { return m_definedFunctionsByName.init([&]{ std::multimap result; @@ -386,7 +385,7 @@ TypeDeclarationAnnotation& UserDefinedValueTypeDefinition::annotation() const std::vector, std::optional>> UsingForDirective::functionsAndOperators() const { - return ranges::zip_view(m_functionsOrLibrary, m_operators) | ranges::to; + return ranges::zip_view(m_functionsOrLibrary, m_operators) | ranges::to; } 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> const* parameters = nullptr; + std::vector> const* parameters = nullptr; if (auto const* funTypeName = dynamic_cast(scope())) parameters = &funTypeName->parameterTypes(); @@ -722,7 +721,7 @@ bool VariableDeclaration::isLocalOrReturn() const bool VariableDeclaration::isReturnParameter() const { - vector> const* returnParameters = nullptr; + std::vector> const* returnParameters = nullptr; if (auto const* funTypeName = dynamic_cast(scope())) returnParameters = &funTypeName->returnParameterTypes(); @@ -813,15 +812,15 @@ bool VariableDeclaration::isFileLevelVariable() const return dynamic_cast(scope()); } -set VariableDeclaration::allowedDataLocations() const +std::set VariableDeclaration::allowedDataLocations() const { using Location = VariableDeclaration::Location; if (!hasReferenceOrMappingType() || isStateVariable() || isEventOrErrorParameter()) - return set{ Location::Unspecified }; + return std::set{ Location::Unspecified }; else if (isCallableOrCatchParameter()) { - set locations{ Location::Memory }; + std::set locations{ Location::Memory }; if ( isConstructorParameter() || isInternalCallableParameter() || @@ -835,13 +834,13 @@ set VariableDeclaration::allowedDataLocations() c } else if (isLocalVariable()) // Further restrictions will be imposed later on. - return set{ Location::Memory, Location::Storage, Location::CallData }; + return std::set{ Location::Memory, Location::Storage, Location::CallData }; else // Struct members etc. - return set{ Location::Unspecified }; + return std::set{ 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(); } -vector> FunctionCall::sortedArguments() const +std::vector> FunctionCall::sortedArguments() const { // normal arguments if (m_names.empty()) @@ -975,7 +974,7 @@ vector> FunctionCall::sortedArguments() const else functionType = dynamic_cast(m_expression->annotation().type); - vector> sorted; + std::vector> 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); } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index f807e6688067..4f9d5714f501 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -87,15 +87,19 @@ class ASTNode static void listAccept(std::vector const& _list, ASTVisitor& _visitor) { for (T const& element: _list) - if (element) - element->accept(_visitor); + { + solAssert(element); + element->accept(_visitor); + } } template static void listAccept(std::vector const& _list, ASTConstVisitor& _visitor) { for (T const& element: _list) - if (element) - element->accept(_visitor); + { + solAssert(element); + element->accept(_visitor); + } } /// @returns a copy of the vector containing only the nodes which derive from T. diff --git a/libsolidity/ast/ASTAnnotations.cpp b/libsolidity/ast/ASTAnnotations.cpp index 3556041d849c..84d49fa2fd37 100644 --- a/libsolidity/ast/ASTAnnotations.cpp +++ b/libsolidity/ast/ASTAnnotations.cpp @@ -23,7 +23,6 @@ #include -using namespace std; using namespace solidity; using namespace solidity::frontend; diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 2573015c2734..9a19907117eb 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -238,6 +238,7 @@ struct TryCatchClauseAnnotation: ASTAnnotation, ScopableAnnotation struct ForStatementAnnotation: StatementAnnotation, ScopableAnnotation { + util::SetOnce isSimpleCounterLoop; }; struct ReturnAnnotation: StatementAnnotation diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index da7f769362fe..98a368d1958f 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -44,7 +44,6 @@ #include #include -using namespace std; using namespace std::string_literals; using namespace solidity::langutil; @@ -52,14 +51,14 @@ namespace { template typename C> -void addIfSet(std::vector>& _attributes, string const& _name, C const& _value) +void addIfSet(std::vector>& _attributes, std::string const& _name, C const& _value) { if constexpr (std::is_same_v, solidity::util::SetOnce>) { if (!_value.set()) return; } - else if constexpr (std::is_same_v, optional>) + else if constexpr (std::is_same_v, std::optional>) { if (!_value.has_value()) return; @@ -73,7 +72,7 @@ void addIfSet(std::vector>& _attributes, string const& namespace solidity::frontend { -ASTJsonExporter::ASTJsonExporter(CompilerStack::State _stackState, map _sourceIndices): +ASTJsonExporter::ASTJsonExporter(CompilerStack::State _stackState, std::map _sourceIndices): m_stackState(_stackState), m_sourceIndices(std::move(_sourceIndices)) { @@ -82,21 +81,21 @@ ASTJsonExporter::ASTJsonExporter(CompilerStack::State _stackState, map>&& _attributes + std::string const& _nodeName, + std::initializer_list>&& _attributes ) { ASTJsonExporter::setJsonNode( _node, _nodeName, - std::vector>(std::move(_attributes)) + std::vector>(std::move(_attributes)) ); } void ASTJsonExporter::setJsonNode( ASTNode const& _node, - string const& _nodeType, - std::vector>&& _attributes + std::string const& _nodeType, + std::vector>&& _attributes ) { m_currentValue = Json::objectValue; @@ -110,24 +109,24 @@ void ASTJsonExporter::setJsonNode( m_currentValue[e.first] = std::move(e.second); } -optional ASTJsonExporter::sourceIndexFromLocation(SourceLocation const& _location) const +std::optional 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 sourceIndexOpt = sourceIndexFromLocation(_location); + std::optional 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 const& _sourceLocations) const +Json::Value ASTJsonExporter::sourceLocationsToJson(std::vector const& _sourceLocations) const { Json::Value locations = Json::arrayValue; @@ -137,7 +136,7 @@ Json::Value ASTJsonExporter::sourceLocationsToJson(vector const& return locations; } -string ASTJsonExporter::namePathToString(std::vector const& _namePath) +std::string ASTJsonExporter::namePathToString(std::vector const& _namePath) { return boost::algorithm::join(_namePath, "."s); } @@ -164,13 +163,13 @@ Json::Value ASTJsonExporter::typePointerToJson(std::optional } void ASTJsonExporter::appendExpressionAttributes( - std::vector>& _attributes, + std::vector>& _attributes, ExpressionAnnotation const& _annotation ) { - std::vector> exprAttributes = { - make_pair("typeDescriptions", typePointerToJson(_annotation.type)), - make_pair("argumentTypes", typePointerToJson(_annotation.arguments)) + std::vector> 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 _info) const +Json::Value ASTJsonExporter::inlineAssemblyIdentifierToJson(std::pair _info) const { Json::Value tuple(Json::objectValue); tuple["src"] = sourceLocationToString(nativeLocationOf(*_info.first)); @@ -199,7 +198,7 @@ Json::Value ASTJsonExporter::inlineAssemblyIdentifierToJson(pair> attributes = { - make_pair("license", _node.licenseString() ? Json::Value(*_node.licenseString()) : Json::nullValue), - make_pair("nodes", toJson(_node.nodes())), + std::vector> 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> attributes = { - make_pair("file", _node.path()), - make_pair("sourceUnit", idOrNull(_node.annotation().sourceUnit)), - make_pair("scope", idOrNull(_node.scope())) + std::vector> 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> 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> 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> attributes = { - make_pair("typeName", _node.typeName() ? toJson(*_node.typeName()) : Json::nullValue) + std::vector> 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> 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> 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> 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> 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> attributes = { - make_pair("name", _node.name()), - make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), - make_pair("underlyingType", toJson(*_node.underlyingType())) + std::vector> 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> 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> 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; + std::optional 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> 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> 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> 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> 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> attributes{ - make_pair("modifierName", toJson(_node.name())), - make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json::nullValue) + std::vector> 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> _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> _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> _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> _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> attributes = { - make_pair("name", _node.typeName().toString()), - make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true)) + std::vector> 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> externalReferences; + std::vector> 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> attributes = { - make_pair("AST", Json::Value(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations()))), - make_pair("externalReferences", std::move(externalReferencesJson)), - make_pair("evmVersion", dynamic_cast(_node.dialect()).evmVersion().name()) + std::vector> 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(_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; @@ -743,12 +742,18 @@ 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::vector> attributes = { + 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())) + }; + + if (_node.annotation().isSimpleCounterLoop.set()) + attributes.emplace_back("isSimpleCounterLoop", *_node.annotation().isSimpleCounterLoop); + + setJsonNode(_node, "ForStatement", std::move(attributes)); return false; } @@ -767,8 +772,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 +787,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 +795,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 +806,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 +816,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> attributes = { - make_pair("condition", toJson(_node.condition())), - make_pair("trueExpression", toJson(_node.trueExpression())), - make_pair("falseExpression", toJson(_node.falseExpression())) + std::vector> 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 +835,10 @@ bool ASTJsonExporter::visit(Conditional const& _node) bool ASTJsonExporter::visit(Assignment const& _node) { - std::vector> attributes = { - make_pair("operator", TokenTraits::toString(_node.assignmentOperator())), - make_pair("leftHandSide", toJson(_node.leftHandSide())), - make_pair("rightHandSide", toJson(_node.rightHandSide())) + std::vector> 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 +847,9 @@ bool ASTJsonExporter::visit(Assignment const& _node) bool ASTJsonExporter::visit(TupleExpression const& _node) { - std::vector> attributes = { - make_pair("isInlineArray", Json::Value(_node.isInlineArray())), - make_pair("components", toJson(_node.components())), + std::vector> 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 +858,10 @@ bool ASTJsonExporter::visit(TupleExpression const& _node) bool ASTJsonExporter::visit(UnaryOperation const& _node) { - std::vector> attributes = { - make_pair("prefix", _node.isPrefixOperation()), - make_pair("operator", TokenTraits::toString(_node.getOperator())), - make_pair("subExpression", toJson(_node.subExpression())) + std::vector> 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 +873,11 @@ bool ASTJsonExporter::visit(UnaryOperation const& _node) bool ASTJsonExporter::visit(BinaryOperation const& _node) { - std::vector> 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> 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 +892,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> 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> 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 +917,10 @@ bool ASTJsonExporter::visit(FunctionCallOptions const& _node) for (auto const& name: _node.names()) names.append(Json::Value(*name)); - std::vector> attributes = { - make_pair("expression", toJson(_node.expression())), - make_pair("names", std::move(names)), - make_pair("options", toJson(_node.options())), + std::vector> 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 +930,8 @@ bool ASTJsonExporter::visit(FunctionCallOptions const& _node) bool ASTJsonExporter::visit(NewExpression const& _node) { - std::vector> attributes = { - make_pair("typeName", toJson(_node.typeName())) + std::vector> attributes = { + std::make_pair("typeName", toJson(_node.typeName())) }; appendExpressionAttributes(attributes, _node.annotation()); setJsonNode(_node, "NewExpression", std::move(attributes)); @@ -935,11 +940,11 @@ bool ASTJsonExporter::visit(NewExpression const& _node) bool ASTJsonExporter::visit(MemberAccess const& _node) { - std::vector> 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> 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 +953,9 @@ bool ASTJsonExporter::visit(MemberAccess const& _node) bool ASTJsonExporter::visit(IndexAccess const& _node) { - std::vector> attributes = { - make_pair("baseExpression", toJson(_node.baseExpression())), - make_pair("indexExpression", toJsonOrNull(_node.indexExpression())), + std::vector> 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 +964,10 @@ bool ASTJsonExporter::visit(IndexAccess const& _node) bool ASTJsonExporter::visit(IndexRangeAccess const& _node) { - std::vector> attributes = { - make_pair("baseExpression", toJson(_node.baseExpression())), - make_pair("startExpression", toJsonOrNull(_node.startExpression())), - make_pair("endExpression", toJsonOrNull(_node.endExpression())), + std::vector> 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 +980,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> attributes = { - make_pair("typeName", toJson(_node.type())) + std::vector> attributes = { + std::make_pair("typeName", toJson(_node.type())) }; appendExpressionAttributes(attributes, _node.annotation()); setJsonNode(_node, "ElementaryTypeNameExpression", std::move(attributes)); @@ -1000,11 +1005,11 @@ bool ASTJsonExporter::visit(Literal const& _node) if (!util::validateUTF8(_node.value())) value = Json::nullValue; Token subdenomination = Token(_node.subDenomination()); - std::vector> attributes = { - make_pair("kind", literalTokenKind(_node.token())), - make_pair("value", value), - make_pair("hexValue", util::toHex(util::asBytes(_node.value()))), - make_pair( + std::vector> 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 +1024,8 @@ bool ASTJsonExporter::visit(Literal const& _node) bool ASTJsonExporter::visit(StructuredDocumentation const& _node) { Json::Value text{*_node.text()}; - std::vector> attributes = { - make_pair("text", text) + std::vector> attributes = { + std::make_pair("text", text) }; setJsonNode(_node, "StructuredDocumentation", std::move(attributes)); return false; @@ -1033,7 +1038,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 +1055,7 @@ string ASTJsonExporter::location(VariableDeclaration::Location _location) return {}; } -string ASTJsonExporter::contractKind(ContractKind _kind) +std::string ASTJsonExporter::contractKind(ContractKind _kind) { switch (_kind) { @@ -1066,7 +1071,7 @@ string ASTJsonExporter::contractKind(ContractKind _kind) return {}; } -string ASTJsonExporter::functionCallKind(FunctionCallKind _kind) +std::string ASTJsonExporter::functionCallKind(FunctionCallKind _kind) { switch (_kind) { @@ -1081,7 +1086,7 @@ string ASTJsonExporter::functionCallKind(FunctionCallKind _kind) } } -string ASTJsonExporter::literalTokenKind(Token _token) +std::string ASTJsonExporter::literalTokenKind(Token _token) { switch (_token) { @@ -1101,12 +1106,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"; } diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index dd7098aabf9a..6e6dd9eb5eeb 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -37,8 +37,6 @@ #include #include -using namespace std; - namespace solidity::frontend { @@ -50,16 +48,16 @@ ASTPointer ASTJsonImporter::nullOrCast(Json::Value const& _json) if (_json.isNull()) return nullptr; else - return dynamic_pointer_cast(convertJsonToASTNode(_json)); + return std::dynamic_pointer_cast(convertJsonToASTNode(_json)); } // ============ public =========================== -map> ASTJsonImporter::jsonToSourceUnit(map const& _sourceList) +std::map> ASTJsonImporter::jsonToSourceUnit(std::map const& _sourceList) { for (auto const& src: _sourceList) - m_sourceNames.emplace_back(make_shared(src.first)); + m_sourceNames.emplace_back(std::make_shared(src.first)); for (auto const& srcPair: _sourceList) { astAssert(!srcPair.second.isNull()); @@ -81,7 +79,7 @@ ASTPointer ASTJsonImporter::createASTNode(Json::Value const& _node, Args&&... astAssert(m_usedIDs.insert(id).second, "Found duplicate node ID!"); - auto n = make_shared( + auto n = std::make_shared( id, createSourceLocation(_node), std::forward(_args)... @@ -96,9 +94,9 @@ SourceLocation const ASTJsonImporter::createSourceLocation(Json::Value const& _n return solidity::langutil::parseSourceLocation(_node["src"].asString(), m_sourceNames); } -optional> ASTJsonImporter::createSourceLocations(Json::Value const& _node) const +std::optional> ASTJsonImporter::createSourceLocations(Json::Value const& _node) const { - vector locations; + std::vector locations; if (_node.isMember("nameLocations") && _node["nameLocations"].isArray()) { @@ -107,7 +105,7 @@ optional> 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 ASTPointer ASTJsonImporter::convertJsonToASTNode(Json::Value const& _node) { - ASTPointer ret = dynamic_pointer_cast(convertJsonToASTNode(_node)); + ASTPointer ret = std::dynamic_pointer_cast(convertJsonToASTNode(_node)); astAssert(ret, "cast of converted json-node must not be nullptr"); return ret; } @@ -143,7 +141,7 @@ ASTPointer ASTJsonImporter::convertJsonToASTNode(Json::Value const& _node) ASTPointer 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 ASTJsonImporter::convertJsonToASTNode(Json::Value const& _js // ============ functions to instantiate the AST-Nodes from Json-Nodes ============== -ASTPointer ASTJsonImporter::createSourceUnit(Json::Value const& _node, string const& _srcName) +ASTPointer ASTJsonImporter::createSourceUnit(Json::Value const& _node, std::string const& _srcName) { - optional license; + std::optional license; if (_node.isMember("license") && !_node["license"].isNull()) license = _node["license"].asString(); @@ -275,7 +273,7 @@ ASTPointer ASTJsonImporter::createSourceUnit(Json::Value const& _nod if (_node.isMember("experimentalSolidity") && !_node["experimentalSolidity"].isNull()) experimentalSolidity = _node["experimentalSolidity"].asBool(); - vector> nodes; + std::vector> nodes; for (auto& child: member(_node, "nodes")) nodes.emplace_back(convertJsonToASTNode(child)); @@ -286,11 +284,11 @@ ASTPointer ASTJsonImporter::createSourceUnit(Json::Value const& _nod ASTPointer ASTJsonImporter::createPragmaDirective(Json::Value const& _node) { - vector tokens; - vector literals; + std::vector tokens; + std::vector 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 ASTJsonImporter::createImportDirective(Json::Value c symbolAliases.push_back({ createIdentifier(tuple["foreign"]), - tuple["local"].isNull() ? nullptr : make_shared(tuple["local"].asString()), + tuple["local"].isNull() ? nullptr : std::make_shared(tuple["local"].asString()), createSourceLocation(tuple["foreign"])} ); } @@ -343,7 +341,7 @@ ASTPointer ASTJsonImporter::createContractDefinition(Json::V return createASTNode( _node, - make_shared(_node["name"].asString()), + std::make_shared(_node["name"].asString()), createNameSourceLocation(_node), _node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")), baseContracts, @@ -357,13 +355,13 @@ ASTPointer ASTJsonImporter::createIdentifierPath(Json::Value con { astAssert(_node["name"].isString(), "Expected 'name' to be a string!"); - vector namePath; - vector namePathLocations; - vector strs; - string nameString = member(_node, "name").asString(); + std::vector namePath; + std::vector namePathLocations; + std::vector 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 ASTJsonImporter::createInheritanceSpecifier(Jso return createASTNode( _node, createIdentifierPath(member(_node, "baseName")), - member(_node, "arguments").isNull() ? nullptr : make_unique>>(arguments) + member(_node, "arguments").isNull() ? nullptr : std::make_unique>>(arguments) ); } ASTPointer ASTJsonImporter::createUsingForDirective(Json::Value const& _node) { - vector> functions; - vector> operators; + std::vector> functions; + std::vector> 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 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 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 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 ASTJsonImporter::createVariableDeclaration(Json: return createASTNode( _node, nullOrCast(member(_node, "typeName")), - make_shared(member(_node, "name").asString()), + std::make_shared(member(_node, "name").asString()), createNameSourceLocation(_node), nullOrCast(member(_node, "value")), visibility(_node), @@ -626,7 +624,7 @@ ASTPointer ASTJsonImporter::createModifierInvocation(Json::V return createASTNode( _node, createIdentifierPath(member(_node, "modifierName")), - member(_node, "arguments").isNull() ? nullptr : make_unique>>(arguments) + member(_node, "arguments").isNull() ? nullptr : std::make_unique>>(arguments) ); } @@ -660,9 +658,9 @@ ASTPointer 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 mutability = {}; @@ -721,19 +719,19 @@ ASTPointer 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>> flags; + ASTPointer>> flags; if (_node.isMember("flags")) { - flags = make_shared>>(); + flags = std::make_shared>>(); 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(flagsNode[i].asString())); + flags->emplace_back(std::make_shared(flagsNode[i].asString())); } } - shared_ptr operations = make_shared(yul::AsmJsonImporter(m_sourceNames).createBlock(member(_node, "AST"))); + std::shared_ptr operations = std::make_shared(yul::AsmJsonImporter(m_sourceNames).createBlock(member(_node, "AST"))); return createASTNode( _node, nullOrASTString(_node, "documentation"), @@ -787,7 +785,7 @@ ASTPointer ASTJsonImporter::createTryCatchClause(Json::Value con ASTPointer ASTJsonImporter::createTryStatement(Json::Value const& _node) { - vector> clauses; + std::vector> clauses; for (auto& param: _node["clauses"]) clauses.emplace_back(createTryCatchClause(param)); @@ -957,10 +955,10 @@ ASTPointer 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(name.asString())); + names.push_back(std::make_shared(name.asString())); } - optional> sourceLocations = createSourceLocations(_node); + std::optional> sourceLocations = createSourceLocations(_node); return createASTNode( _node, @@ -969,7 +967,7 @@ ASTPointer ASTJsonImporter::createFunctionCall(Json::Value const& names, sourceLocations ? *sourceLocations : - vector(names.size()) + std::vector(names.size()) ); } @@ -982,7 +980,7 @@ ASTPointer ASTJsonImporter::createFunctionCallOptions(Json: for (auto& name: member(_node, "names")) { astAssert(name.isString(), "Expected 'names' members to be strings!"); - names.push_back(make_shared(name.asString())); + names.push_back(std::make_shared(name.asString())); } return createASTNode( @@ -1049,14 +1047,14 @@ ASTPointer ASTJsonImporter::createElementaryTypeNa ASTPointer 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 value = _node.isMember(hexValStr) ? - make_shared(util::asString(util::fromHex(_node[hexValStr].asString()))) : - make_shared(_node[valStr].asString()); + std::make_shared(util::asString(util::fromHex(_node[hexValStr].asString()))) : + std::make_shared(_node[valStr].asString()); return createASTNode( _node, @@ -1068,19 +1066,19 @@ ASTPointer ASTJsonImporter::createLiteral(Json::Value const& _node) ASTPointer 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( _node, - make_shared(_node[textString].asString()) + std::make_shared(_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 ASTJsonImporter::nullOrASTString(Json::Value const& _json, string const& _name) +ASTPointer ASTJsonImporter::nullOrASTString(Json::Value const& _json, std::string const& _name) { return _json[_name].isString() ? memberAsASTString(_json, _name) : nullptr; } -ASTPointer ASTJsonImporter::memberAsASTString(Json::Value const& _node, string const& _name) +ASTPointer 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(_node[_name].asString()); + return std::make_shared(_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; diff --git a/libsolidity/ast/CallGraph.cpp b/libsolidity/ast/CallGraph.cpp index bf37b2264d2f..04275c374034 100644 --- a/libsolidity/ast/CallGraph.cpp +++ b/libsolidity/ast/CallGraph.cpp @@ -18,7 +18,6 @@ #include -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(_lhs)) - return get(_lhs) < get(_rhs); - return get(_lhs)->id() < get(_rhs)->id(); + if (std::holds_alternative(_lhs)) + return std::get(_lhs) < std::get(_rhs); + return std::get(_lhs)->id() < std::get(_rhs)->id(); } bool CallGraph::CompareByID::operator()(Node const& _lhs, int64_t _rhs) const { - solAssert(!holds_alternative(_lhs), ""); + solAssert(!std::holds_alternative(_lhs), ""); - return get(_lhs)->id() < _rhs; + return std::get(_lhs)->id() < _rhs; } bool CallGraph::CompareByID::operator()(int64_t _lhs, Node const& _rhs) const { - solAssert(!holds_alternative(_rhs), ""); + solAssert(!std::holds_alternative(_rhs), ""); - return _lhs < get(_rhs)->id(); + return _lhs < std::get(_rhs)->id(); } diff --git a/libsolidity/ast/TypeProvider.cpp b/libsolidity/ast/TypeProvider.cpp index 2ccd46457764..98215b86ade5 100644 --- a/libsolidity/ast/TypeProvider.cpp +++ b/libsolidity/ast/TypeProvider.cpp @@ -21,7 +21,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::frontend; using namespace solidity::util; @@ -31,128 +30,128 @@ 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 TypeProvider::m_bytesStorage; -unique_ptr TypeProvider::m_bytesMemory; -unique_ptr TypeProvider::m_bytesCalldata; -unique_ptr TypeProvider::m_stringStorage; -unique_ptr TypeProvider::m_stringMemory; +std::unique_ptr TypeProvider::m_bytesStorage; +std::unique_ptr TypeProvider::m_bytesMemory; +std::unique_ptr TypeProvider::m_bytesCalldata; +std::unique_ptr TypeProvider::m_stringStorage; +std::unique_ptr TypeProvider::m_stringMemory; TupleType const TypeProvider::m_emptyTuple{}; AddressType const TypeProvider::m_payableAddress{StateMutability::Payable}; AddressType const TypeProvider::m_address{StateMutability::NonPayable}; IntegerType const TypeProvider::m_trcToken{256, IntegerType::Modifier::TrcToken}; -array, 32> const TypeProvider::m_intM{{ - {make_unique(8 * 1, IntegerType::Modifier::Signed)}, - {make_unique(8 * 2, IntegerType::Modifier::Signed)}, - {make_unique(8 * 3, IntegerType::Modifier::Signed)}, - {make_unique(8 * 4, IntegerType::Modifier::Signed)}, - {make_unique(8 * 5, IntegerType::Modifier::Signed)}, - {make_unique(8 * 6, IntegerType::Modifier::Signed)}, - {make_unique(8 * 7, IntegerType::Modifier::Signed)}, - {make_unique(8 * 8, IntegerType::Modifier::Signed)}, - {make_unique(8 * 9, IntegerType::Modifier::Signed)}, - {make_unique(8 * 10, IntegerType::Modifier::Signed)}, - {make_unique(8 * 11, IntegerType::Modifier::Signed)}, - {make_unique(8 * 12, IntegerType::Modifier::Signed)}, - {make_unique(8 * 13, IntegerType::Modifier::Signed)}, - {make_unique(8 * 14, IntegerType::Modifier::Signed)}, - {make_unique(8 * 15, IntegerType::Modifier::Signed)}, - {make_unique(8 * 16, IntegerType::Modifier::Signed)}, - {make_unique(8 * 17, IntegerType::Modifier::Signed)}, - {make_unique(8 * 18, IntegerType::Modifier::Signed)}, - {make_unique(8 * 19, IntegerType::Modifier::Signed)}, - {make_unique(8 * 20, IntegerType::Modifier::Signed)}, - {make_unique(8 * 21, IntegerType::Modifier::Signed)}, - {make_unique(8 * 22, IntegerType::Modifier::Signed)}, - {make_unique(8 * 23, IntegerType::Modifier::Signed)}, - {make_unique(8 * 24, IntegerType::Modifier::Signed)}, - {make_unique(8 * 25, IntegerType::Modifier::Signed)}, - {make_unique(8 * 26, IntegerType::Modifier::Signed)}, - {make_unique(8 * 27, IntegerType::Modifier::Signed)}, - {make_unique(8 * 28, IntegerType::Modifier::Signed)}, - {make_unique(8 * 29, IntegerType::Modifier::Signed)}, - {make_unique(8 * 30, IntegerType::Modifier::Signed)}, - {make_unique(8 * 31, IntegerType::Modifier::Signed)}, - {make_unique(8 * 32, IntegerType::Modifier::Signed)} +std::array, 32> const TypeProvider::m_intM{{ + {std::make_unique(8 * 1, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 2, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 3, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 4, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 5, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 6, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 7, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 8, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 9, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 10, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 11, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 12, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 13, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 14, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 15, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 16, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 17, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 18, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 19, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 20, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 21, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 22, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 23, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 24, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 25, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 26, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 27, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 28, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 29, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 30, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 31, IntegerType::Modifier::Signed)}, + {std::make_unique(8 * 32, IntegerType::Modifier::Signed)} }}; -array, 32> const TypeProvider::m_uintM{{ - {make_unique(8 * 1, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 2, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 3, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 4, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 5, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 6, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 7, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 8, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 9, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 10, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 11, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 12, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 13, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 14, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 15, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 16, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 17, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 18, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 19, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 20, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 21, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 22, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 23, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 24, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 25, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 26, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 27, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 28, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 29, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 30, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 31, IntegerType::Modifier::Unsigned)}, - {make_unique(8 * 32, IntegerType::Modifier::Unsigned)} +std::array, 32> const TypeProvider::m_uintM{{ + {std::make_unique(8 * 1, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 2, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 3, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 4, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 5, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 6, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 7, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 8, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 9, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 10, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 11, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 12, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 13, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 14, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 15, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 16, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 17, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 18, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 19, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 20, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 21, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 22, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 23, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 24, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 25, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 26, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 27, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 28, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 29, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 30, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 31, IntegerType::Modifier::Unsigned)}, + {std::make_unique(8 * 32, IntegerType::Modifier::Unsigned)} }}; -array, 32> const TypeProvider::m_bytesM{{ - {make_unique(1)}, - {make_unique(2)}, - {make_unique(3)}, - {make_unique(4)}, - {make_unique(5)}, - {make_unique(6)}, - {make_unique(7)}, - {make_unique(8)}, - {make_unique(9)}, - {make_unique(10)}, - {make_unique(11)}, - {make_unique(12)}, - {make_unique(13)}, - {make_unique(14)}, - {make_unique(15)}, - {make_unique(16)}, - {make_unique(17)}, - {make_unique(18)}, - {make_unique(19)}, - {make_unique(20)}, - {make_unique(21)}, - {make_unique(22)}, - {make_unique(23)}, - {make_unique(24)}, - {make_unique(25)}, - {make_unique(26)}, - {make_unique(27)}, - {make_unique(28)}, - {make_unique(29)}, - {make_unique(30)}, - {make_unique(31)}, - {make_unique(32)} +std::array, 32> const TypeProvider::m_bytesM{{ + {std::make_unique(1)}, + {std::make_unique(2)}, + {std::make_unique(3)}, + {std::make_unique(4)}, + {std::make_unique(5)}, + {std::make_unique(6)}, + {std::make_unique(7)}, + {std::make_unique(8)}, + {std::make_unique(9)}, + {std::make_unique(10)}, + {std::make_unique(11)}, + {std::make_unique(12)}, + {std::make_unique(13)}, + {std::make_unique(14)}, + {std::make_unique(15)}, + {std::make_unique(16)}, + {std::make_unique(17)}, + {std::make_unique(18)}, + {std::make_unique(19)}, + {std::make_unique(20)}, + {std::make_unique(21)}, + {std::make_unique(22)}, + {std::make_unique(23)}, + {std::make_unique(24)}, + {std::make_unique(25)}, + {std::make_unique(26)}, + {std::make_unique(27)}, + {std::make_unique(28)}, + {std::make_unique(29)}, + {std::make_unique(30)}, + {std::make_unique(31)}, + {std::make_unique(32)} }}; -array, 5> const TypeProvider::m_magics{{ - {make_unique(MagicType::Kind::Chain)}, - {make_unique(MagicType::Kind::Block)}, - {make_unique(MagicType::Kind::Message)}, - {make_unique(MagicType::Kind::Transaction)}, - {make_unique(MagicType::Kind::ABI)} +std::array, 5> const TypeProvider::m_magics{{ + {std::make_unique(MagicType::Kind::Chain)}, + {std::make_unique(MagicType::Kind::Block)}, + {std::make_unique(MagicType::Kind::Message)}, + {std::make_unique(MagicType::Kind::Transaction)}, + {std::make_unique(MagicType::Kind::ABI)} // MetaType is stored separately }}; @@ -162,7 +161,7 @@ inline void clearCache(Type const& type) } template -inline void clearCache(unique_ptr const& type) +inline void clearCache(std::unique_ptr const& type) { // Some lazy-initialized types might not exist yet. if (type) @@ -203,7 +202,7 @@ void TypeProvider::reset() template inline T const* TypeProvider::createAndGet(Args&& ... _args) { - instance().m_generalTypes.emplace_back(make_unique(std::forward(_args)...)); + instance().m_generalTypes.emplace_back(std::make_unique(std::forward(_args)...)); return static_cast(instance().m_generalTypes.back().get()); } @@ -264,15 +263,15 @@ Type const* TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken const& } } -Type const* TypeProvider::fromElementaryTypeName(string const& _name) +Type const* TypeProvider::fromElementaryTypeName(std::string const& _name) { - vector nameParts; + std::vector 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(t)) @@ -312,35 +311,35 @@ Type const* TypeProvider::fromElementaryTypeName(string const& _name) ArrayType const* TypeProvider::bytesStorage() { if (!m_bytesStorage) - m_bytesStorage = make_unique(DataLocation::Storage, false); + m_bytesStorage = std::make_unique(DataLocation::Storage, false); return m_bytesStorage.get(); } ArrayType const* TypeProvider::bytesMemory() { if (!m_bytesMemory) - m_bytesMemory = make_unique(DataLocation::Memory, false); + m_bytesMemory = std::make_unique(DataLocation::Memory, false); return m_bytesMemory.get(); } ArrayType const* TypeProvider::bytesCalldata() { if (!m_bytesCalldata) - m_bytesCalldata = make_unique(DataLocation::CallData, false); + m_bytesCalldata = std::make_unique(DataLocation::CallData, false); return m_bytesCalldata.get(); } ArrayType const* TypeProvider::stringStorage() { if (!m_stringStorage) - m_stringStorage = make_unique(DataLocation::Storage, true); + m_stringStorage = std::make_unique(DataLocation::Storage, true); return m_stringStorage.get(); } ArrayType const* TypeProvider::stringMemory() { if (!m_stringMemory) - m_stringMemory = make_unique(DataLocation::Memory, true); + m_stringMemory = std::make_unique(DataLocation::Memory, true); return m_stringMemory.get(); } @@ -381,30 +380,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(literal)).first->second.get(); + return instance().m_stringLiteralTypes.emplace(literal, std::make_unique(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(m, n, _modifier) + std::make_pair(m, n), + std::make_unique(m, n, _modifier) ).first->second.get(); } -TupleType const* TypeProvider::tuple(vector members) +TupleType const* TypeProvider::tuple(std::vector members) { if (members.empty()) return &m_emptyTuple; diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 1c3931994194..5fdfec40e287 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -54,7 +54,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::langutil; using namespace solidity::frontend; @@ -111,7 +110,7 @@ util::Result transformParametersToExternal(TypePointers const& _pa return transformed; } -string toStringInParentheses(TypePointers const& _types, bool _withoutDataLocation) +std::string toStringInParentheses(TypePointers const& _types, bool _withoutDataLocation) { return '(' + util::joinHumanReadable( _types | ranges::views::transform([&](auto const* _type) { return _type->toString(_withoutDataLocation); }), @@ -125,7 +124,7 @@ MemberList::Member::Member(Declaration const* _declaration, Type const* _type): Member(_declaration, _type, _declaration->name()) {} -MemberList::Member::Member(Declaration const* _declaration, Type const* _type, string _name): +MemberList::Member::Member(Declaration const* _declaration, Type const* _type, std::string _name): name(std::move(_name)), type(_type), declaration(_declaration) @@ -143,7 +142,7 @@ void StorageOffsets::computeOffsets(TypePointers const& _types) { bigint slotOffset = 0; unsigned byteOffset = 0; - map> offsets; + std::map> offsets; for (size_t i = 0; i < _types.size(); ++i) { Type const* type = _types[i]; @@ -156,7 +155,7 @@ void StorageOffsets::computeOffsets(TypePointers const& _types) byteOffset = 0; } solAssert(slotOffset < bigint(1) << 256 ,"Object too large for storage."); - offsets[i] = make_pair(u256(slotOffset), byteOffset); + offsets[i] = std::make_pair(u256(slotOffset), byteOffset); solAssert(type->storageSize() >= 1, "Invalid storage size."); if (type->storageSize() == 1 && byteOffset + type->storageBytes() <= 32) byteOffset += type->storageBytes(); @@ -173,7 +172,7 @@ void StorageOffsets::computeOffsets(TypePointers const& _types) swap(m_offsets, offsets); } -pair const* StorageOffsets::offset(size_t _index) const +std::pair const* StorageOffsets::offset(size_t _index) const { if (m_offsets.count(_index)) return &m_offsets.at(_index); @@ -186,7 +185,7 @@ void MemberList::combine(MemberList const & _other) m_memberTypes += _other.m_memberTypes; } -pair const* MemberList::memberStorageOffset(string const& _name) const +std::pair const* MemberList::memberStorageOffset(std::string const& _name) const { StorageOffsets const& offsets = storageOffsets(); @@ -219,33 +218,33 @@ StorageOffsets const& MemberList::storageOffsets() const { namespace { -string parenthesizeIdentifier(string const& _internal) +std::string parenthesizeIdentifier(std::string const& _internal) { return "(" + _internal + ")"; } template -string identifierList(Range const&& _list) +std::string identifierList(Range const&& _list) { return parenthesizeIdentifier(boost::algorithm::join(_list, ",")); } -string richIdentifier(Type const* _type) +std::string richIdentifier(Type const* _type) { return _type ? _type->richIdentifier() : ""; } -string identifierList(vector const& _list) +std::string identifierList(std::vector const& _list) { return identifierList(_list | ranges::views::transform(richIdentifier)); } -string identifierList(Type const* _type) +std::string identifierList(Type const* _type) { return parenthesizeIdentifier(richIdentifier(_type)); } -string identifierList(Type const* _type1, Type const* _type2) +std::string identifierList(Type const* _type1, Type const* _type2) { TypePointers list; list.push_back(_type1); @@ -253,16 +252,16 @@ string identifierList(Type const* _type1, Type const* _type2) return identifierList(list); } -string parenthesizeUserIdentifier(string const& _internal) +std::string parenthesizeUserIdentifier(std::string const& _internal) { return parenthesizeIdentifier(_internal); } } -string Type::escapeIdentifier(string const& _identifier) +std::string Type::escapeIdentifier(std::string const& _identifier) { - string ret = _identifier; + std::string ret = _identifier; // FIXME: should be _$$$_ boost::algorithm::replace_all(ret, "$", "$$$"); boost::algorithm::replace_all(ret, ",", "_$_"); @@ -271,12 +270,12 @@ string Type::escapeIdentifier(string const& _identifier) return ret; } -string Type::identifier() const +std::string Type::identifier() const { - string ret = escapeIdentifier(richIdentifier()); + std::string ret = escapeIdentifier(richIdentifier()); solAssert(ret.find_first_of("0123456789") != 0, "Identifier cannot start with a number."); solAssert( - ret.find_first_not_of("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMONPQRSTUVWXYZ_$") == string::npos, + ret.find_first_not_of("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMONPQRSTUVWXYZ_$") == std::string::npos, "Identifier contains invalid characters." ); return ret; @@ -306,7 +305,7 @@ MemberList const& Type::members(ASTNode const* _currentScope) const MemberList::MemberMap members = nativeMembers(_currentScope); if (_currentScope) members += attachedFunctions(*this, *_currentScope); - m_members[_currentScope] = make_unique(std::move(members)); + m_members[_currentScope] = std::make_unique(std::move(members)); } return *m_members[_currentScope]; } @@ -341,9 +340,9 @@ Type const* Type::fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool) c namespace { -vector usingForDirectivesForType(Type const& _type, ASTNode const& _scope) +std::vector usingForDirectivesForType(Type const& _type, ASTNode const& _scope) { - vector usingForDirectives; + std::vector usingForDirectives; SourceUnit const* sourceUnit = dynamic_cast(&_scope); if (auto const* contract = dynamic_cast(&_scope)) { @@ -378,12 +377,12 @@ vector usingForDirectivesForType(Type const& _type, AS _directive->typeName()->annotation().type, true ); - }) | ranges::to>; + }) | ranges::to>; } } -set Type::operatorDefinitions( +std::set Type::operatorDefinitions( Token _token, ASTNode const& _scope, bool _unary @@ -392,7 +391,7 @@ set Type::operatorDefinitions( if (!typeDefinition()) return {}; - set matchingDefinitions; + std::set matchingDefinitions; for (UsingForDirective const* directive: usingForDirectivesForType(*this, _scope)) for (auto const& [identifierPath, operator_]: directive->functionsAndOperators()) { @@ -419,8 +418,8 @@ MemberList::MemberMap Type::attachedFunctions(Type const& _type, ASTNode const& { MemberList::MemberMap members; - set> seenFunctions; - auto addFunction = [&](FunctionDefinition const& _function, optional _name = {}) + std::set> seenFunctions; + auto addFunction = [&](FunctionDefinition const& _function, std::optional _name = {}) { if (!_name) _name = _function.name(); @@ -432,7 +431,7 @@ MemberList::MemberMap Type::attachedFunctions(Type const& _type, ASTNode const& solAssert(withBoundFirstArgument, ""); if (_type.isImplicitlyConvertibleTo(*withBoundFirstArgument->selfType())) - if (seenFunctions.insert(make_pair(*_name, &_function)).second) + if (seenFunctions.insert(std::make_pair(*_name, &_function)).second) members.emplace_back(&_function, withBoundFirstArgument, *_name); }; @@ -474,7 +473,7 @@ AddressType::AddressType(StateMutability _stateMutability): solAssert(m_stateMutability == StateMutability::Payable || m_stateMutability == StateMutability::NonPayable, ""); } -string AddressType::richIdentifier() const +std::string AddressType::richIdentifier() const { if (m_stateMutability == StateMutability::Payable) return "t_address_payable"; @@ -508,7 +507,7 @@ BoolResult AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const return false; } -string AddressType::toString(bool) const +std::string AddressType::toString(bool) const { if (m_stateMutability == StateMutability::Payable) return "address payable"; @@ -516,7 +515,7 @@ string AddressType::toString(bool) const return "address"; } -string AddressType::canonicalName() const +std::string AddressType::canonicalName() const { return "address"; } @@ -684,12 +683,12 @@ IntegerType::IntegerType(unsigned _bits, IntegerType::Modifier _modifier): ); } -string IntegerType::richIdentifier() const +std::string IntegerType::richIdentifier() const { if (isTrcToken()) return "t_trcToken"; else - return "t_" + string(isSigned() ? "" : "u") + "int" + to_string(numBits()); + return "t_" + std::string(isSigned() ? "" : "u") + "int" + std::to_string(numBits()); } BoolResult IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const @@ -767,11 +766,11 @@ bool IntegerType::operator==(Type const& _other) const return other.m_bits == m_bits && other.m_modifier == m_modifier; } -string IntegerType::toString(bool) const +std::string IntegerType::toString(bool) const { if (isTrcToken()) return "trcToken"; - string prefix = isSigned() ? "int" : "uint"; + std::string prefix = isSigned() ? "int" : "uint"; return prefix + util::toString(m_bits); } @@ -868,9 +867,9 @@ FixedPointType::FixedPointType(unsigned _totalBits, unsigned _fractionalDigits, ); } -string FixedPointType::richIdentifier() const +std::string FixedPointType::richIdentifier() const { - return "t_" + string(isSigned() ? "" : "u") + "fixed" + to_string(m_totalBits) + "x" + to_string(m_fractionalDigits); + return "t_" + std::string(isSigned() ? "" : "u") + "fixed" + std::to_string(m_totalBits) + "x" + std::to_string(m_fractionalDigits); } BoolResult FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const @@ -920,9 +919,9 @@ bool FixedPointType::operator==(Type const& _other) const return other.m_totalBits == m_totalBits && other.m_fractionalDigits == m_fractionalDigits && other.m_modifier == m_modifier; } -string FixedPointType::toString(bool) const +std::string FixedPointType::toString(bool) const { - string prefix = isSigned() ? "fixed" : "ufixed"; + std::string prefix = isSigned() ? "fixed" : "ufixed"; return prefix + util::toString(m_totalBits) + "x" + util::toString(m_fractionalDigits); } @@ -963,7 +962,7 @@ IntegerType const* FixedPointType::asIntegerType() const return TypeProvider::integer(numBits(), isSigned() ? IntegerType::Modifier::Signed : IntegerType::Modifier::Unsigned); } -tuple RationalNumberType::parseRational(string const& _value) +std::tuple RationalNumberType::parseRational(std::string const& _value) { rational value; try @@ -976,7 +975,7 @@ tuple RationalNumberType::parseRational(string const& _value) !all_of(radixPoint + 1, _value.end(), util::isDigit) || !all_of(_value.begin(), radixPoint, util::isDigit) ) - return make_tuple(false, rational(0)); + return std::make_tuple(false, rational(0)); // Only decimal notation allowed here, leading zeros would switch to octal. auto fractionalBegin = find_if_not( @@ -988,25 +987,25 @@ tuple RationalNumberType::parseRational(string const& _value) rational numerator; rational denominator(1); - denominator = bigint(string(fractionalBegin, _value.end())); + denominator = bigint(std::string(fractionalBegin, _value.end())); denominator /= boost::multiprecision::pow( bigint(10), static_cast(distance(radixPoint + 1, _value.end())) ); - numerator = bigint(string(_value.begin(), radixPoint)); + numerator = bigint(std::string(_value.begin(), radixPoint)); value = numerator + denominator; } else value = bigint(_value); - return make_tuple(true, value); + return std::make_tuple(true, value); } catch (...) { - return make_tuple(false, rational(0)); + return std::make_tuple(false, rational(0)); } } -tuple RationalNumberType::isValidLiteral(Literal const& _literal) +std::tuple RationalNumberType::isValidLiteral(Literal const& _literal) { rational value; try @@ -1025,27 +1024,27 @@ tuple RationalNumberType::isValidLiteral(Literal const& _literal else if (expPoint != valueString.end()) { // Parse mantissa and exponent. Checks numeric limit. - tuple mantissa = parseRational(string(valueString.begin(), expPoint)); + std::tuple mantissa = parseRational(std::string(valueString.begin(), expPoint)); - if (!get<0>(mantissa)) - return make_tuple(false, rational(0)); - value = get<1>(mantissa); + if (!std::get<0>(mantissa)) + return std::make_tuple(false, rational(0)); + value = std::get<1>(mantissa); // 0E... is always zero. if (value == 0) - return make_tuple(true, rational(0)); + return std::make_tuple(true, rational(0)); - bigint exp = bigint(string(expPoint + 1, valueString.end())); + bigint exp = bigint(std::string(expPoint + 1, valueString.end())); - if (exp > numeric_limits::max() || exp < numeric_limits::min()) - return make_tuple(false, rational(0)); + if (exp > std::numeric_limits::max() || exp < std::numeric_limits::min()) + return std::make_tuple(false, rational(0)); uint32_t expAbs = bigint(abs(exp)).convert_to(); if (exp < 0) { if (!fitsPrecisionBase10(abs(value.denominator()), expAbs)) - return make_tuple(false, rational(0)); + return std::make_tuple(false, rational(0)); value /= boost::multiprecision::pow( bigint(10), expAbs @@ -1054,7 +1053,7 @@ tuple RationalNumberType::isValidLiteral(Literal const& _literal else if (exp > 0) { if (!fitsPrecisionBase10(abs(value.numerator()), expAbs)) - return make_tuple(false, rational(0)); + return std::make_tuple(false, rational(0)); value *= boost::multiprecision::pow( bigint(10), expAbs @@ -1064,15 +1063,15 @@ tuple RationalNumberType::isValidLiteral(Literal const& _literal else { // parse as rational number - tuple tmp = parseRational(valueString); - if (!get<0>(tmp)) + std::tuple tmp = parseRational(valueString); + if (!std::get<0>(tmp)) return tmp; - value = get<1>(tmp); + value = std::get<1>(tmp); } } catch (...) { - return make_tuple(false, rational(0)); + return std::make_tuple(false, rational(0)); } switch (_literal.subDenomination()) { @@ -1108,7 +1107,7 @@ tuple RationalNumberType::isValidLiteral(Literal const& _literal } - return make_tuple(true, value); + return std::make_tuple(true, value); } BoolResult RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const @@ -1171,7 +1170,7 @@ BoolResult RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) TypeResult RationalNumberType::unaryOperatorResult(Token _operator) const { - if (optional value = ConstantEvaluator::evaluateUnaryOperator(_operator, m_value)) + if (std::optional value = ConstantEvaluator::evaluateUnaryOperator(_operator, m_value)) return TypeResult{TypeProvider::rationalNumber(*value)}; else return nullptr; @@ -1229,10 +1228,10 @@ TypeResult RationalNumberType::binaryOperatorResult(Token _operator, Type const* return nullptr; return thisMobile->binaryOperatorResult(_operator, otherMobile); } - else if (optional value = ConstantEvaluator::evaluateBinaryOperator(_operator, m_value, other.m_value)) + else if (std::optional value = ConstantEvaluator::evaluateBinaryOperator(_operator, m_value, other.m_value)) { // verify that numerator and denominator fit into 4096 bit after every operation - if (value->numerator() != 0 && max(boost::multiprecision::msb(abs(value->numerator())), boost::multiprecision::msb(abs(value->denominator()))) > 4096) + if (value->numerator() != 0 && std::max(boost::multiprecision::msb(abs(value->numerator())), boost::multiprecision::msb(abs(value->denominator()))) > 4096) return TypeResult::err("Precision of rational constants is limited to 4096 bits."); return TypeResult{TypeProvider::rationalNumber(*value)}; @@ -1241,7 +1240,7 @@ TypeResult RationalNumberType::binaryOperatorResult(Token _operator, Type const* return nullptr; } -string RationalNumberType::richIdentifier() const +std::string RationalNumberType::richIdentifier() const { // rational seemingly will put the sign always on the numerator, // but let just make it deterministic here. @@ -1261,24 +1260,24 @@ bool RationalNumberType::operator==(Type const& _other) const return m_value == other.m_value; } -string RationalNumberType::bigintToReadableString(bigint const& _num) +std::string RationalNumberType::bigintToReadableString(bigint const& _num) { - string str = _num.str(); + std::string str = _num.str(); if (str.size() > 32) { size_t omitted = str.size() - 8; - str = str.substr(0, 4) + "...(" + to_string(omitted) + " digits omitted)..." + str.substr(str.size() - 4, 4); + str = str.substr(0, 4) + "...(" + std::to_string(omitted) + " digits omitted)..." + str.substr(str.size() - 4, 4); } return str; } -string RationalNumberType::toString(bool) const +std::string RationalNumberType::toString(bool) const { if (!isFractional()) return "int_const " + bigintToReadableString(m_value.numerator()); - string numerator = bigintToReadableString(m_value.numerator()); - string denominator = bigintToReadableString(m_value.denominator()); + std::string numerator = bigintToReadableString(m_value.numerator()); + std::string denominator = bigintToReadableString(m_value.denominator()); return "rational_const " + numerator + " / " + denominator; } @@ -1330,7 +1329,7 @@ IntegerType const* RationalNumberType::integerType() const return nullptr; else return TypeProvider::integer( - max(numberEncodingSize(value), 1u) * 8, + std::max(numberEncodingSize(value), 1u) * 8, negative ? IntegerType::Modifier::Signed : IntegerType::Modifier::Unsigned ); } @@ -1364,7 +1363,7 @@ FixedPointType const* RationalNumberType::fixedPointType() const if (v > u256(-1)) return nullptr; - unsigned totalBits = max(numberEncodingSize(v), 1u) * 8; + unsigned totalBits = std::max(numberEncodingSize(v), 1u) * 8; solAssert(totalBits <= 256, ""); return TypeProvider::fixedPoint( @@ -1378,7 +1377,7 @@ StringLiteralType::StringLiteralType(Literal const& _literal): { } -StringLiteralType::StringLiteralType(string _value): +StringLiteralType::StringLiteralType(std::string _value): m_value{std::move(_value)} { } @@ -1409,9 +1408,9 @@ BoolResult StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) return false; } -string StringLiteralType::richIdentifier() const +std::string StringLiteralType::richIdentifier() const { - // Since we have to return a valid identifier and the string itself may contain + // Since we have to return a valid identifier and the std::string itself may contain // anything, we hash it. return "t_stringliteral_" + util::toHex(util::keccak256(m_value).asBytes()); } @@ -1425,7 +1424,7 @@ bool StringLiteralType::operator==(Type const& _other) const std::string StringLiteralType::toString(bool) const { - auto isPrintableASCII = [](string const& s) + auto isPrintableASCII = [](std::string const& s) { for (auto c: s) { @@ -1514,9 +1513,9 @@ MemberList::MemberMap FixedBytesType::nativeMembers(ASTNode const*) const return MemberList::MemberMap{MemberList::Member{"length", TypeProvider::uint(8)}}; } -string FixedBytesType::richIdentifier() const +std::string FixedBytesType::richIdentifier() const { - return "t_bytes" + to_string(m_bytes); + return "t_bytes" + std::to_string(m_bytes); } bool FixedBytesType::operator==(Type const& _other) const @@ -1620,10 +1619,10 @@ TypeResult ContractType::unaryOperatorResult(Token _operator) const return nullptr; } -vector CompositeType::fullDecomposition() const +std::vector CompositeType::fullDecomposition() const { - vector res = {this}; - unordered_set seen = {richIdentifier()}; + std::vector res = {this}; + std::unordered_set seen = {richIdentifier()}; for (size_t k = 0; k < res.size(); ++k) if (auto composite = dynamic_cast(res[k])) for (Type const* next: composite->decomposition()) @@ -1671,12 +1670,12 @@ Type const* ReferenceType::copyForLocationIfReference(Type const* _type) const return TypeProvider::withLocationIfReference(m_location, _type); } -string ReferenceType::stringForReferencePart() const +std::string ReferenceType::stringForReferencePart() const { switch (m_location) { case DataLocation::Storage: - return string("storage ") + (isPointer() ? "pointer" : "ref"); + return std::string("storage ") + (isPointer() ? "pointer" : "ref"); case DataLocation::CallData: return "calldata"; case DataLocation::Memory: @@ -1686,9 +1685,9 @@ string ReferenceType::stringForReferencePart() const return ""; } -string ReferenceType::identifierLocationSuffix() const +std::string ReferenceType::identifierLocationSuffix() const { - string id; + std::string id; switch (location()) { case DataLocation::Storage: @@ -1765,7 +1764,7 @@ BoolResult ArrayType::isExplicitlyConvertibleTo(Type const& _convertTo) const { if (isImplicitlyConvertibleTo(_convertTo)) return true; - // allow conversion bytes <-> string and bytes -> bytesNN + // allow conversion bytes <-> std::string and bytes -> bytesNN if (_convertTo.category() != category()) return isByteArray() && _convertTo.category() == Type::Category::FixedBytes; auto& convertTo = dynamic_cast(_convertTo); @@ -1776,9 +1775,9 @@ BoolResult ArrayType::isExplicitlyConvertibleTo(Type const& _convertTo) const return true; } -string ArrayType::richIdentifier() const +std::string ArrayType::richIdentifier() const { - string id; + std::string id; if (isString()) id = "t_string"; else if (isByteArrayOrString()) @@ -1844,13 +1843,13 @@ BoolResult ArrayType::validForLocation(DataLocation _loc) const size *= type->memoryHeadSize(); else size *= type->memoryDataSize(); - if (size >= numeric_limits::max()) + if (size >= std::numeric_limits::max()) return BoolResult::err("Type too large for memory."); break; } case DataLocation::CallData: { - if (unlimitedStaticCalldataSize(true) >= numeric_limits::max()) + if (unlimitedStaticCalldataSize(true) >= std::numeric_limits::max()) return BoolResult::err("Type too large for calldata."); break; } @@ -1875,7 +1874,7 @@ unsigned ArrayType::calldataEncodedSize(bool _padded) const { solAssert(!isDynamicallyEncoded(), ""); bigint size = unlimitedStaticCalldataSize(_padded); - solAssert(size <= numeric_limits::max(), "Array size does not fit unsigned."); + solAssert(size <= std::numeric_limits::max(), "Array size does not fit unsigned."); return unsigned(size); } @@ -1887,7 +1886,7 @@ unsigned ArrayType::calldataEncodedTailSize() const // length must still be present. return 32; bigint size = unlimitedStaticCalldataSize(false); - solAssert(size <= numeric_limits::max(), "Array size does not fit unsigned."); + solAssert(size <= std::numeric_limits::max(), "Array size does not fit unsigned."); return unsigned(size); } @@ -1921,10 +1920,10 @@ u256 ArrayType::storageSize() const else size = bigint(length()) * baseType()->storageSize(); solAssert(size < bigint(1) << 256, "Array too large for storage."); - return max(1, u256(size)); + return std::max(1, u256(size)); } -vector> ArrayType::makeStackItems() const +std::vector> ArrayType::makeStackItems() const { switch (m_location) { @@ -1942,9 +1941,9 @@ vector> ArrayType::makeStackItems() const solAssert(false, ""); } -string ArrayType::toString(bool _withoutDataLocation) const +std::string ArrayType::toString(bool _withoutDataLocation) const { - string ret; + std::string ret; if (isString()) ret = "string"; else if (isByteArrayOrString()) @@ -1961,9 +1960,9 @@ string ArrayType::toString(bool _withoutDataLocation) const return ret; } -string ArrayType::humanReadableName() const +std::string ArrayType::humanReadableName() const { - string ret; + std::string ret; if (isString()) ret = "string"; else if (isByteArrayOrString()) @@ -1979,9 +1978,9 @@ string ArrayType::humanReadableName() const return ret; } -string ArrayType::canonicalName() const +std::string ArrayType::canonicalName() const { - string ret; + std::string ret; if (isString()) ret = "string"; else if (isByteArrayOrString()) @@ -1996,7 +1995,7 @@ string ArrayType::canonicalName() const return ret; } -string ArrayType::signatureInExternalFunction(bool _structsByName) const +std::string ArrayType::signatureInExternalFunction(bool _structsByName) const { if (isByteArrayOrString()) return canonicalName(); @@ -2023,21 +2022,21 @@ MemberList::MemberMap ArrayType::nativeMembers(ASTNode const*) const members.emplace_back("push", TypeProvider::function( TypePointers{thisAsPointer}, TypePointers{baseType()}, - strings{string()}, - strings{string()}, + strings{std::string()}, + strings{std::string()}, FunctionType::Kind::ArrayPush )->withBoundFirstArgument()); members.emplace_back("push", TypeProvider::function( TypePointers{thisAsPointer, baseType()}, TypePointers{}, - strings{string(),string()}, + strings{std::string(),std::string()}, strings{}, FunctionType::Kind::ArrayPush )->withBoundFirstArgument()); members.emplace_back("pop", TypeProvider::function( TypePointers{thisAsPointer}, TypePointers{}, - strings{string()}, + strings{std::string()}, strings{}, FunctionType::Kind::ArrayPop )->withBoundFirstArgument()); @@ -2115,13 +2114,13 @@ u256 ArrayType::memoryDataSize() const solAssert(m_location == DataLocation::Memory, ""); solAssert(!isByteArrayOrString(), ""); bigint size = bigint(m_length) * m_baseType->memoryHeadSize(); - solAssert(size <= numeric_limits::max(), "Array size does not fit u256."); + solAssert(size <= std::numeric_limits::max(), "Array size does not fit u256."); return u256(size); } std::unique_ptr ArrayType::copyForLocation(DataLocation _location, bool _isPointer) const { - auto copy = make_unique(_location); + auto copy = std::make_unique(_location); if (_location == DataLocation::Storage) copy->m_isPointer = _isPointer; copy->m_arrayKind = m_arrayKind; @@ -2149,7 +2148,7 @@ BoolResult ArraySliceType::isExplicitlyConvertibleTo(Type const& _convertTo) con m_arrayType.isExplicitlyConvertibleTo(_convertTo); } -string ArraySliceType::richIdentifier() const +std::string ArraySliceType::richIdentifier() const { return m_arrayType.richIdentifier() + "_slice"; } @@ -2161,12 +2160,12 @@ bool ArraySliceType::operator==(Type const& _other) const return false; } -string ArraySliceType::toString(bool _withoutDataLocation) const +std::string ArraySliceType::toString(bool _withoutDataLocation) const { return m_arrayType.toString(_withoutDataLocation) + " slice"; } -string ArraySliceType::humanReadableName() const +std::string ArraySliceType::humanReadableName() const { return m_arrayType.humanReadableName() + " slice"; } @@ -2189,9 +2188,9 @@ std::vector> ArraySliceType::makeStackItems return {{"offset", TypeProvider::uint256()}, {"length", TypeProvider::uint256()}}; } -string ContractType::richIdentifier() const +std::string ContractType::richIdentifier() const { - return (m_super ? "t_super" : "t_contract") + parenthesizeUserIdentifier(m_contract.name()) + to_string(m_contract.id()); + return (m_super ? "t_super" : "t_contract") + parenthesizeUserIdentifier(m_contract.name()) + std::to_string(m_contract.id()); } bool ContractType::operator==(Type const& _other) const @@ -2202,15 +2201,15 @@ bool ContractType::operator==(Type const& _other) const return other.m_contract == m_contract && other.m_super == m_super; } -string ContractType::toString(bool) const +std::string ContractType::toString(bool) const { return - string(m_contract.isLibrary() ? "library " : "contract ") + - string(m_super ? "super " : "") + + std::string(m_contract.isLibrary() ? "library " : "contract ") + + std::string(m_super ? "super " : "") + m_contract.name(); } -string ContractType::canonicalName() const +std::string ContractType::canonicalName() const { return *m_contract.annotation().canonicalName; } @@ -2236,9 +2235,9 @@ FunctionType const* ContractType::newExpressionType() const return m_constructorType; } -vector> ContractType::stateVariables() const +std::vector> ContractType::stateVariables() const { - vector variables; + std::vector variables; for (ContractDefinition const* contract: m_contract.annotation().linearizedBaseContracts | ranges::views::reverse) for (VariableDeclaration const* variable: contract->stateVariables()) if (!(variable->isConstant() || variable->immutable())) @@ -2249,16 +2248,16 @@ vector> ContractType::stateVar StorageOffsets offsets; offsets.computeOffsets(types); - vector> variablesAndOffsets; + std::vector> variablesAndOffsets; for (size_t index = 0; index < variables.size(); ++index) if (auto const* offset = offsets.offset(index)) variablesAndOffsets.emplace_back(variables[index], offset->first, offset->second); return variablesAndOffsets; } -vector ContractType::immutableVariables() const +std::vector ContractType::immutableVariables() const { - vector variables; + std::vector variables; for (ContractDefinition const* contract: m_contract.annotation().linearizedBaseContracts | ranges::views::reverse) for (VariableDeclaration const* variable: contract->stateVariables()) if (variable->immutable()) @@ -2266,12 +2265,12 @@ vector ContractType::immutableVariables() const return variables; } -vector> ContractType::makeStackItems() const +std::vector> ContractType::makeStackItems() const { if (m_super) return {}; else - return {make_tuple("address", isPayable() ? TypeProvider::payableAddress() : TypeProvider::address())}; + return {std::make_tuple("address", isPayable() ? TypeProvider::payableAddress() : TypeProvider::address())}; } void StructType::clearCache() const @@ -2303,9 +2302,9 @@ BoolResult StructType::isImplicitlyConvertibleTo(Type const& _convertTo) const return this->m_struct == convertTo.m_struct; } -string StructType::richIdentifier() const +std::string StructType::richIdentifier() const { - return "t_struct" + parenthesizeUserIdentifier(m_struct.name()) + to_string(m_struct.id()) + identifierLocationSuffix(); + return "t_struct" + parenthesizeUserIdentifier(m_struct.name()) + std::to_string(m_struct.id()) + identifierLocationSuffix(); } bool StructType::operator==(Type const& _other) const @@ -2393,7 +2392,7 @@ bigint StructType::storageSizeUpperBound() const u256 StructType::storageSize() const { - return max(1, members(nullptr).storageSize()); + return std::max(1, members(nullptr).storageSize()); } bool StructType::containsNestedMapping() const @@ -2432,9 +2431,9 @@ bool StructType::containsNestedMapping() const return m_struct.annotation().containsNestedMapping.value(); } -string StructType::toString(bool _withoutDataLocation) const +std::string StructType::toString(bool _withoutDataLocation) const { - string ret = "struct " + *m_struct.annotation().canonicalName; + std::string ret = "struct " + *m_struct.annotation().canonicalName; if (!_withoutDataLocation) ret += " " + stringForReferencePart(); return ret; @@ -2591,20 +2590,20 @@ bool StructType::recursive() const std::unique_ptr StructType::copyForLocation(DataLocation _location, bool _isPointer) const { - auto copy = make_unique(m_struct, _location); + auto copy = std::make_unique(m_struct, _location); if (_location == DataLocation::Storage) copy->m_isPointer = _isPointer; return copy; } -string StructType::signatureInExternalFunction(bool _structsByName) const +std::string StructType::signatureInExternalFunction(bool _structsByName) const { if (_structsByName) return canonicalName(); else { TypePointers memberTypes = memoryMemberTypes(); - auto memberTypeStrings = memberTypes | ranges::views::transform([&](Type const* _t) -> string + auto memberTypeStrings = memberTypes | ranges::views::transform([&](Type const* _t) -> std::string { solAssert(_t, "Parameter should have external type."); auto t = _t->interfaceType(_structsByName); @@ -2615,7 +2614,7 @@ string StructType::signatureInExternalFunction(bool _structsByName) const } } -string StructType::canonicalName() const +std::string StructType::canonicalName() const { return *m_struct.annotation().canonicalName; } @@ -2639,14 +2638,14 @@ FunctionTypePointer StructType::constructorType() const ); } -pair const& StructType::storageOffsetsOfMember(string const& _name) const +std::pair const& StructType::storageOffsetsOfMember(std::string const& _name) const { auto const* offsets = members(nullptr).memberStorageOffset(_name); solAssert(offsets, "Storage offset of non-existing member requested."); return *offsets; } -u256 StructType::memoryOffsetOfMember(string const& _name) const +u256 StructType::memoryOffsetOfMember(std::string const& _name) const { u256 offset; for (auto const& member: members(nullptr)) @@ -2668,7 +2667,7 @@ TypePointers StructType::memoryMemberTypes() const return types; } -vector> StructType::makeStackItems() const +std::vector> StructType::makeStackItems() const { switch (m_location) { @@ -2682,9 +2681,9 @@ vector> StructType::makeStackItems() const solAssert(false, ""); } -vector StructType::decomposition() const +std::vector StructType::decomposition() const { - vector res; + std::vector res; for (MemberList::Member const& member: members(nullptr)) res.push_back(member.type); return res; @@ -2706,9 +2705,9 @@ TypeResult EnumType::unaryOperatorResult(Token _operator) const return _operator == Token::Delete ? TypeProvider::emptyTuple() : nullptr; } -string EnumType::richIdentifier() const +std::string EnumType::richIdentifier() const { - return "t_enum" + parenthesizeUserIdentifier(m_enum.name()) + to_string(m_enum.id()); + return "t_enum" + parenthesizeUserIdentifier(m_enum.name()) + std::to_string(m_enum.id()); } bool EnumType::operator==(Type const& _other) const @@ -2725,12 +2724,12 @@ unsigned EnumType::storageBytes() const return 1; } -string EnumType::toString(bool) const +std::string EnumType::toString(bool) const { - return string("enum ") + *m_enum.annotation().canonicalName; + return std::string("enum ") + *m_enum.annotation().canonicalName; } -string EnumType::canonicalName() const +std::string EnumType::canonicalName() const { return *m_enum.annotation().canonicalName; } @@ -2774,9 +2773,9 @@ Declaration const* UserDefinedValueType::typeDefinition() const return &m_definition; } -string UserDefinedValueType::richIdentifier() const +std::string UserDefinedValueType::richIdentifier() const { - return "t_userDefinedValueType" + parenthesizeIdentifier(m_definition.name()) + to_string(m_definition.id()); + return "t_userDefinedValueType" + parenthesizeIdentifier(m_definition.name()) + std::to_string(m_definition.id()); } bool UserDefinedValueType::operator==(Type const& _other) const @@ -2787,17 +2786,17 @@ bool UserDefinedValueType::operator==(Type const& _other) const return other.definition() == definition(); } -string UserDefinedValueType::toString(bool /* _withoutDataLocation */) const +std::string UserDefinedValueType::toString(bool /* _withoutDataLocation */) const { return *definition().annotation().canonicalName; } -string UserDefinedValueType::canonicalName() const +std::string UserDefinedValueType::canonicalName() const { return *definition().annotation().canonicalName; } -vector> UserDefinedValueType::makeStackItems() const +std::vector> UserDefinedValueType::makeStackItems() const { return underlyingType().stackItems(); } @@ -2822,7 +2821,7 @@ BoolResult TupleType::isImplicitlyConvertibleTo(Type const& _other) const return false; } -string TupleType::richIdentifier() const +std::string TupleType::richIdentifier() const { return "t_tuple" + identifierList(components()); } @@ -2835,22 +2834,22 @@ bool TupleType::operator==(Type const& _other) const return false; } -string TupleType::toString(bool _withoutDataLocation) const +std::string TupleType::toString(bool _withoutDataLocation) const { if (components().empty()) return "tuple()"; - string str = "tuple("; + std::string str = "tuple("; for (auto const& t: components()) str += (t ? t->toString(_withoutDataLocation) : "") + ","; str.pop_back(); return str + ")"; } -string TupleType::humanReadableName() const +std::string TupleType::humanReadableName() const { if (components().empty()) return "tuple()"; - string str = "tuple("; + std::string str = "tuple("; for (auto const& t: components()) str += (t ? t->humanReadableName() : "") + ","; str.pop_back(); @@ -2862,9 +2861,9 @@ u256 TupleType::storageSize() const solAssert(false, "Storage size of non-storable tuple type requested."); } -vector> TupleType::makeStackItems() const +std::vector> TupleType::makeStackItems() const { - vector> slots; + std::vector> slots; unsigned i = 1; for (auto const& t: components()) { @@ -3099,11 +3098,11 @@ FunctionTypePointer FunctionType::newExpressionType(ContractDefinition const& _c ); } -vector FunctionType::parameterNames() const +std::vector FunctionType::parameterNames() const { if (!hasBoundFirstArgument()) return m_parameterNames; - return vector(m_parameterNames.cbegin() + 1, m_parameterNames.cend()); + return std::vector(m_parameterNames.cbegin() + 1, m_parameterNames.cend()); } TypePointers FunctionType::returnParameterTypesWithoutDynamicTypes() const @@ -3140,9 +3139,9 @@ TypePointers const& FunctionType::parameterTypesIncludingSelf() const return m_parameterTypes; } -string FunctionType::richIdentifier() const +std::string FunctionType::richIdentifier() const { - string id = "t_function_"; + std::string id = "t_function_"; switch (m_kind) { case Kind::Declaration: id += "declaration"; break; @@ -3323,13 +3322,13 @@ TypeResult FunctionType::binaryOperatorResult(Token _operator, Type const* _othe return nullptr; } -string FunctionType::canonicalName() const +std::string FunctionType::canonicalName() const { solAssert(m_kind == Kind::External, ""); return "function"; } -string FunctionType::humanReadableName() const +std::string FunctionType::humanReadableName() const { switch (m_kind) { @@ -3342,9 +3341,9 @@ string FunctionType::humanReadableName() const } } -string FunctionType::toString(bool _withoutDataLocation) const +std::string FunctionType::toString(bool _withoutDataLocation) const { - string name = "function "; + std::string name = "function "; if (m_kind == Kind::Declaration) { auto const* functionDefinition = dynamic_cast(m_declaration); @@ -3408,9 +3407,9 @@ bool FunctionType::nameable() const !saltSet(); } -vector> FunctionType::makeStackItems() const +std::vector> FunctionType::makeStackItems() const { - vector> slots; + std::vector> slots; Kind kind = m_kind; if (m_kind == Kind::SetGas || m_kind == Kind::SetValue) { @@ -3423,8 +3422,8 @@ vector> FunctionType::makeStackItems() const case Kind::External: case Kind::DelegateCall: slots = { - make_tuple("address", TypeProvider::address()), - make_tuple("functionSelector", TypeProvider::uint(32)) + std::make_tuple("address", TypeProvider::address()), + std::make_tuple("functionSelector", TypeProvider::uint(32)) }; break; case Kind::BareCall: @@ -3433,10 +3432,10 @@ vector> FunctionType::makeStackItems() const case Kind::BareStaticCall: case Kind::Transfer: case Kind::Send: - slots = {make_tuple("address", TypeProvider::address())}; + slots = {std::make_tuple("address", TypeProvider::address())}; break; case Kind::Internal: - slots = {make_tuple("functionIdentifier", TypeProvider::uint256())}; + slots = {std::make_tuple("functionIdentifier", TypeProvider::uint256())}; break; case Kind::ArrayPush: case Kind::ArrayPop: @@ -3765,7 +3764,7 @@ bool FunctionType::isBareCall() const } } -string FunctionType::externalSignature() const +std::string FunctionType::externalSignature() const { solAssert(m_declaration != nullptr, "External signature of function needs declaration"); solAssert(!m_declaration->name().empty(), "Fallback function has no signature."); @@ -3792,9 +3791,9 @@ string FunctionType::externalSignature() const solAssert(extParams.message().empty(), extParams.message()); - auto typeStrings = extParams.get() | ranges::views::transform([&](Type const* _t) -> string + auto typeStrings = extParams.get() | ranges::views::transform([&](Type const* _t) -> std::string { - string typeName = _t->signatureInExternalFunction(inLibrary); + std::string typeName = _t->signatureInExternalFunction(inLibrary); if (inLibrary && _t->dataStoredIn(DataLocation::Storage)) typeName += " storage"; @@ -3808,7 +3807,7 @@ u256 FunctionType::externalIdentifier() const return util::selectorFromSignatureU32(externalSignature()); } -string FunctionType::externalIdentifierHex() const +std::string FunctionType::externalIdentifierHex() const { return util::selectorFromSignatureH32(externalSignature()).hex(); } @@ -3846,7 +3845,7 @@ TypePointers FunctionType::parseElementaryTypeVector(strings const& _types) { TypePointers pointers; pointers.reserve(_types.size()); - for (string const& type: _types) + for (std::string const& type: _types) pointers.push_back(TypeProvider::fromElementaryTypeName(type)); return pointers; } @@ -3972,7 +3971,7 @@ Type const* MappingType::encodingType() const return TypeProvider::integer(256, IntegerType::Modifier::Unsigned); } -string MappingType::richIdentifier() const +std::string MappingType::richIdentifier() const { return "t_mapping" + identifierList(m_keyType, m_valueType); } @@ -3985,12 +3984,12 @@ bool MappingType::operator==(Type const& _other) const return *other.m_keyType == *m_keyType && *other.m_valueType == *m_valueType; } -string MappingType::toString(bool _withoutDataLocation) const +std::string MappingType::toString(bool _withoutDataLocation) const { return "mapping(" + keyType()->toString(_withoutDataLocation) + " => " + valueType()->toString(_withoutDataLocation) + ")"; } -string MappingType::canonicalName() const +std::string MappingType::canonicalName() const { return "mapping(" + keyType()->canonicalName() + " => " + valueType()->canonicalName() + ")"; } @@ -4023,7 +4022,7 @@ std::vector> MappingType::makeStackItems() return {std::make_tuple("slot", TypeProvider::uint256())}; } -string TypeType::richIdentifier() const +std::string TypeType::richIdentifier() const { return "t_type" + identifierList(actualType()); } @@ -4041,13 +4040,13 @@ u256 TypeType::storageSize() const solAssert(false, "Storage size of non-storable type type requested."); } -vector> TypeType::makeStackItems() const +std::vector> TypeType::makeStackItems() const { if (auto contractType = dynamic_cast(m_actualType)) if (contractType->contractDefinition().isLibrary()) { solAssert(!contractType->isSuper(), ""); - return {make_tuple("address", TypeProvider::address())}; + return {std::make_tuple("address", TypeProvider::address())}; } return {}; @@ -4134,8 +4133,8 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons TypeProvider::function( TypePointers{&userDefined.underlyingType()}, TypePointers{&userDefined}, - strings{string{}}, - strings{string{}}, + strings{std::string{}}, + strings{std::string{}}, FunctionType::Kind::Wrap, StateMutability::Pure ) @@ -4145,8 +4144,8 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons TypeProvider::function( TypePointers{&userDefined}, TypePointers{&userDefined.underlyingType()}, - strings{string{}}, - strings{string{}}, + strings{std::string{}}, + strings{std::string{}}, FunctionType::Kind::Unwrap, StateMutability::Pure ) @@ -4160,7 +4159,7 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons TypePointers{}, TypePointers{arrayType->isString() ? TypeProvider::stringMemory() : TypeProvider::bytesMemory()}, strings{}, - strings{string{}}, + strings{std::string{}}, arrayType->isString() ? FunctionType::Kind::StringConcat : FunctionType::Kind::BytesConcat, StateMutability::Pure, nullptr, @@ -4192,7 +4191,7 @@ u256 ModifierType::storageSize() const solAssert(false, "Storage size of non-storable type type requested."); } -string ModifierType::richIdentifier() const +std::string ModifierType::richIdentifier() const { return "t_modifier" + identifierList(m_parameterTypes); } @@ -4217,17 +4216,17 @@ bool ModifierType::operator==(Type const& _other) const return true; } -string ModifierType::toString(bool _withoutDataLocation) const +std::string ModifierType::toString(bool _withoutDataLocation) const { - string name = "modifier ("; + std::string name = "modifier ("; for (auto it = m_parameterTypes.begin(); it != m_parameterTypes.end(); ++it) name += (*it)->toString(_withoutDataLocation) + (it + 1 == m_parameterTypes.end() ? "" : ","); return name + ")"; } -string ModuleType::richIdentifier() const +std::string ModuleType::richIdentifier() const { - return "t_module_" + to_string(m_sourceUnit.id()); + return "t_module_" + std::to_string(m_sourceUnit.id()); } bool ModuleType::operator==(Type const& _other) const @@ -4246,12 +4245,12 @@ MemberList::MemberMap ModuleType::nativeMembers(ASTNode const*) const return symbols; } -string ModuleType::toString(bool) const +std::string ModuleType::toString(bool) const { - return string("module \"") + *m_sourceUnit.annotation().path + string("\""); + return std::string("module \"") + *m_sourceUnit.annotation().path + std::string("\""); } -string MagicType::richIdentifier() const +std::string MagicType::richIdentifier() const { switch (m_kind) { @@ -4430,7 +4429,7 @@ MemberList::MemberMap MagicType::nativeMembers(ASTNode const*) const return {}; } -string MagicType::toString(bool _withoutDataLocation) const +std::string MagicType::toString(bool _withoutDataLocation) const { switch (m_kind) { diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index afd126b6e617..7a79b26fa933 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -30,12 +30,11 @@ #include -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, ), sub(tail, headStart)) tail := ( tail) )") : - string(R"( + std::string(R"( ( add(headStart, )) )") ); - 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 := ( pos) )") : - string(R"( + std::string(R"( ( pos) pos := add(pos, ) )") ); - 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 valueReturnParams; + std::string decodeElements; + std::vector 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 valueNamesLocal; + std::vector 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> members; + std::vector> 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 := (, pos)"} ("encode", abiEncodeAndReturnUpdatedPosFunction(*memberTypeFrom, *memberTypeTo, subOptions)) @@ -942,7 +941,7 @@ string ABIFunctions::abiEncodingFunctionStruct( { Whiskers encodeTempl( dynamicMember ? - string(R"( + std::string(R"( mstore(add(pos, ), sub(tail, pos)) tail := (, 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(_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(_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" : ""); @@ -1151,17 +1150,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"( // @@ -1183,14 +1182,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" : ""); @@ -1241,7 +1240,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()) @@ -1249,7 +1248,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, [&]() { @@ -1290,12 +1289,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" : ""); @@ -1319,10 +1318,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(); @@ -1338,15 +1337,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" : ""); @@ -1373,7 +1372,7 @@ string ABIFunctions::abiDecodingFunctionStruct(StructType const& _type, bool _fr solAssert(_type.memoryDataSize() < u256("0xffffffffffffffff"), ""); templ("memorySize", toCompactHexWithPrefix(_type.memoryDataSize())); size_t headPos = 0; - vector> members; + std::vector> members; for (auto const& member: _type.members(nullptr)) { solAssert(member.type, ""); @@ -1393,7 +1392,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)); @@ -1408,11 +1407,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" : "") + @@ -1447,10 +1446,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()) { @@ -1494,7 +1493,7 @@ string ABIFunctions::calldataAccessFunction(Type const& _type) } else if (_type.isValueType()) { - string decodingFunction; + std::string decodingFunction; if (auto const* functionType = dynamic_cast(&_type)) decodingFunction = abiDecodingFunctionFunctionType(*functionType, false, false); else @@ -1527,9 +1526,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"( @@ -1551,7 +1550,7 @@ string ABIFunctions::arrayStoreLengthForEncodingFunction(ArrayType const& _type, }); } -string ABIFunctions::createFunction(string const& _name, function const& _creator) +std::string ABIFunctions::createFunction(std::string const& _name, std::function const& _creator) { return m_functionCollector.createFunction(_name, _creator); } diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp index 609ff9993ba8..afcc38fe8a11 100644 --- a/libsolidity/codegen/ArrayUtils.cpp +++ b/libsolidity/codegen/ArrayUtils.cpp @@ -36,7 +36,6 @@ #include #include -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; } diff --git a/libsolidity/codegen/Compiler.cpp b/libsolidity/codegen/Compiler.cpp index c044760a022d..844de8ba82c6 100644 --- a/libsolidity/codegen/Compiler.cpp +++ b/libsolidity/codegen/Compiler.cpp @@ -26,13 +26,12 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::frontend; void Compiler::compileContract( ContractDefinition const& _contract, - std::map> const& _otherCompilers, + std::map> const& _otherCompilers, bytes const& _metadata ) { diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index bc69f82c57e8..d9264c6ac5f1 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -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 CompilerContext::immutableVariableSlotNames(VariableDeclaration const& _variable) +std::vector 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 names; - auto collectSlotNames = [&](string const& _baseName, Type const* type, auto const& _recurse) -> void { + std::vector 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 const& _generator + std::function 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 const& _generator + std::function 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 generator; + std::function 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 toRemove; + std::vector toRemove; for (auto _var: m_localVariables) { solAssert(!_var.second.empty(), ""); @@ -250,14 +249,14 @@ unsigned CompilerContext::numberOfLocalVariables() const return static_cast(m_localVariables.size()); } -shared_ptr CompilerContext::compiledContract(ContractDefinition const& _contract) const +std::shared_ptr 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 CompilerContext::compiledContractRuntime(ContractDefinition const& _contract) const +std::shared_ptr 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(m_asm->deposit()) - _offset - 1; } -pair CompilerContext::storageLocationOfVariable(Declaration const& _declaration) const +std::pair 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 newStack; + std::stack newStack; newStack.push(_node); std::swap(m_visitedNodes, newStack); updateSourceLocation(); } void CompilerContext::appendInlineAssembly( - string const& _assembly, - vector const& _localVariables, - set const& _externallyUsedFunctions, + std::string const& _assembly, + std::vector const& _localVariables, + std::set const& _externallyUsedFunctions, bool _system, OptimiserSettings const& _optimiserSettings, - string _sourceName + std::string _sourceName ) { unsigned startStackHeight = stackHeight(); - set externallyUsedIdentifiers; + std::set 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 locationOverride; + std::optional locationOverride; if (!_system) locationOverride = m_asm->currentSourceLocation(); - shared_ptr parserResult = + std::shared_ptr 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(analysisInfo); + obj.analysisInfo = std::make_shared(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(); } diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 783a7b1a45f3..bf4f25bf289e 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -33,7 +33,6 @@ #include #include -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 const& _parameterTypes, - vector const& _argumentTypes + std::string const& _signature, + std::vector const& _parameterTypes, + std::vector 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(32, ((str->value().size() + 31) / 32) * 32)); + m_context << u256(std::max(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, ) { } })"); - 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", 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: - 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(_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 const& offsets = typeOnStack->storageOffsetsOfMember(member.name); + std::pair 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(32u, type->memoryDataSize())); + utils.allocateMemory(std::max(32u, type->memoryDataSize())); _context << Instruction::DUP1; if (auto structType = dynamic_cast(type)) @@ -1493,7 +1492,7 @@ void CompilerUtils::popAndJump(unsigned _toHeight, evmasm::AssemblyItem const& _ m_context.adjustStackOffset(static_cast(amount)); } -unsigned CompilerUtils::sizeOnStack(vector const& _variableTypes) +unsigned CompilerUtils::sizeOnStack(std::vector 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 assembly = + std::shared_ptr assembly = _creation ? _context.compiledContract(contract) : _context.compiledContractRuntime(contract); diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 8d46c0e07a0b..5e4517fb8958 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -55,7 +55,6 @@ #include #include -using namespace std; using namespace solidity; using namespace solidity::evmasm; using namespace solidity::frontend; @@ -80,7 +79,7 @@ class StackHeightChecker { 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 @@ class StackHeightChecker void ContractCompiler::compileContract( ContractDefinition const& _contract, - map> const& _otherCompilers + std::map> const& _otherCompilers ) { CompilerContext::LocationSetter locationSetter(m_context, _contract); @@ -111,7 +110,7 @@ void ContractCompiler::compileContract( size_t ContractCompiler::compileConstructor( ContractDefinition const& _contract, - std::map> const& _otherCompilers + std::map> const& _otherCompilers ) { CompilerContext::LocationSetter locationSetter(m_context, _contract); @@ -126,7 +125,7 @@ size_t ContractCompiler::compileConstructor( void ContractCompiler::initializeContext( ContractDefinition const& _contract, - map> const& _otherCompilers + std::map> const& _otherCompilers ) { m_context.setUseABICoderV2(*_contract.sourceUnit().annotation().useABICoderV2); @@ -193,7 +192,7 @@ size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _cont CompilerContext::LocationSetter locationSetter(m_context, _contract); m_context << deployRoutine; - solAssert(m_context.runtimeSub() != numeric_limits::max(), "Runtime sub not registered"); + solAssert(m_context.runtimeSub() != std::numeric_limits::max(), "Runtime sub not registered"); ContractType contractType(_contract); auto const& immutables = contractType.immutableVariables(); @@ -237,7 +236,7 @@ size_t ContractCompiler::deployLibrary(ContractDefinition const& _contract) CompilerContext::LocationSetter locationSetter(m_context, _contract); - solAssert(m_context.runtimeSub() != numeric_limits::max(), "Runtime sub not registered"); + solAssert(m_context.runtimeSub() != std::numeric_limits::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(). @@ -330,8 +329,8 @@ void ContractCompiler::appendDelegatecallCheck() } void ContractCompiler::appendInternalSelector( - map, evmasm::AssemblyItem const> const& _entryPoints, - vector> const& _ids, + std::map, evmasm::AssemblyItem const> const& _entryPoints, + std::vector> const& _ids, evmasm::AssemblyItem const& _notFoundTag, size_t _runs ) @@ -375,11 +374,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> larger{_ids.begin() + static_cast(pivotIndex), _ids.end()}; + std::vector> larger{_ids.begin() + static_cast(pivotIndex), _ids.end()}; appendInternalSelector(_entryPoints, larger, _notFoundTag, _runs); m_context << lessTag; // Here, we have funid < pivot - vector> smaller{_ids.begin(), _ids.begin() + static_cast(pivotIndex)}; + std::vector> smaller{_ids.begin(), _ids.begin() + static_cast(pivotIndex)}; appendInternalSelector(_entryPoints, smaller, _notFoundTag, _runs); } else @@ -417,8 +416,8 @@ bool hasPayableFunctions(ContractDefinition const& _contract) void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contract) { - map, FunctionTypePointer> interfaceFunctions = _contract.interfaceFunctions(); - map, evmasm::AssemblyItem const> callDataUnpackerEntryPoints; + std::map, FunctionTypePointer> interfaceFunctions = _contract.interfaceFunctions(); + std::map, evmasm::AssemblyItem const> callDataUnpackerEntryPoints; if (_contract.isLibrary()) { @@ -454,7 +453,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac CompilerUtils(m_context).loadFromMemory(0, IntegerType(CompilerUtils::dataStartOffset * 8), true, false); // stack now is: ? - vector> sortedIDs; + std::vector> sortedIDs; for (auto const& it: interfaceFunctions) { callDataUnpackerEntryPoints.emplace(it.first, m_context.newTag()); @@ -578,7 +577,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) @@ -651,7 +650,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) m_breakTags.clear(); m_continueTags.clear(); m_currentFunction = &_function; - m_modifierDepth = numeric_limits::max(); + m_modifierDepth = std::numeric_limits::max(); m_scopeStackHeight.clear(); m_context.setModifierDepth(0); @@ -668,10 +667,10 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) unsigned const c_argumentsSize = CompilerUtils::sizeOnStack(_function.parameters()); unsigned const c_returnValuesSize = CompilerUtils::sizeOnStack(_function.returnParameters()); - vector stackLayout; + std::vector stackLayout; if (!_function.isConstructor() && !_function.isFallback()) stackLayout.push_back(static_cast(c_returnValuesSize)); // target of return address - stackLayout += vector(c_argumentsSize, -1); // discard all arguments + stackLayout += std::vector(c_argumentsSize, -1); // discard all arguments for (size_t i = 0; i < c_returnValuesSize; ++i) stackLayout.push_back(static_cast(i)); @@ -690,7 +689,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) else { m_context << swapInstruction(static_cast(stackLayout.size()) - static_cast(stackLayout.back()) - 1u); - swap(stackLayout[static_cast(stackLayout.back())], stackLayout.back()); + std::swap(stackLayout[static_cast(stackLayout.back())], stackLayout.back()); } for (size_t i = 0; i < stackLayout.size(); ++i) if (stackLayout[i] != static_cast(i)) @@ -796,7 +795,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) unsigned stackDiff = static_cast(_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", ""); @@ -871,7 +870,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) // lvalue context auto variable = dynamic_cast(decl); unsigned stackDiff = static_cast(_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( @@ -934,7 +933,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 @@ -947,8 +946,8 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) solAssert(dialect, ""); // Create a modifiable copy of the code and analysis - object.code = make_shared(yul::ASTCopier().translate(*code)); - object.analysisInfo = make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(*dialect, object)); + object.code = std::make_shared(yul::ASTCopier().translate(*code)); + object.analysisInfo = std::make_shared(yul::AsmAnalyzer::analyzeStrictAssertCorrect(*dialect, object)); m_context.optimizeYul(object, *dialect, m_optimiserSettings); @@ -995,10 +994,10 @@ bool ContractCompiler::visit(TryStatement const& _tryStatement) TryCatchClause const& successClause = *_tryStatement.clauses().front(); if (successClause.parameters()) { - vector exprTypes{_tryStatement.externalCall().annotation().type}; + std::vector exprTypes{_tryStatement.externalCall().annotation().type}; if (auto tupleType = dynamic_cast(exprTypes.front())) exprTypes = tupleType->components(); - vector> const& params = successClause.parameters()->parameters(); + std::vector> 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], ""); @@ -1014,7 +1013,7 @@ bool ContractCompiler::visit(TryStatement const& _tryStatement) return false; } -void ContractCompiler::handleCatch(vector> const& _catchClauses) +void ContractCompiler::handleCatch(std::vector> const& _catchClauses) { // Stack is empty. ASTPointer error{}; @@ -1252,7 +1251,16 @@ bool ContractCompiler::visit(ForStatement const& _forStatement) // for's loop expression if existing if (_forStatement.loopExpression()) + { + Arithmetic previousArithmetic = m_context.arithmetic(); + if ( + *_forStatement.annotation().isSimpleCounterLoop && + m_optimiserSettings.simpleCounterForLoopUncheckedIncrement + ) + m_context.setArithmetic(Arithmetic::Wrapping); _forStatement.loopExpression()->accept(*this); + m_context.setArithmetic(previousArithmetic); + } m_context.appendJumpTo(loopStart); @@ -1291,7 +1299,7 @@ bool ContractCompiler::visit(Return const& _return) if (Expression const* expression = _return.expression()) { solAssert(_return.annotation().functionReturnParameters, "Invalid return parameters pointer."); - vector> const& returnParameters = + std::vector> const& returnParameters = _return.annotation().functionReturnParameters->parameters(); TypePointers types; for (auto const& retVariable: returnParameters) @@ -1438,7 +1446,7 @@ void ContractCompiler::appendModifierOrFunctionCode() solAssert(m_currentFunction, ""); unsigned stackSurplus = 0; Block const* codeBlock = nullptr; - vector addedVariables; + std::vector addedVariables; m_modifierDepth++; m_context.setModifierDepth(m_modifierDepth); diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 9a2a0cf04670..379147620b06 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -43,7 +43,6 @@ #include #include -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(returnTypes[i])) if (!arrayType->isByteArrayOrString()) continue; - pair const& offsets = structType->storageOffsetsOfMember(names[i]); + std::pair 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(*_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> lvalues; + std::vector> 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()); + lvalues.push_back(std::unique_ptr()); if (_tuple.annotation().willBeWrittenTo) { if (_tuple.components().size() == 1) m_currentLValue = std::move(lvalues[0]); else - m_currentLValue = make_unique(m_context, std::move(lvalues)); + m_currentLValue = std::make_unique(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> const& arguments = _functionCall.sortedArguments(); + std::vector> const& arguments = _functionCall.sortedArguments(); if (functionCallKind == FunctionCallKind::StructConstructorCall) { TypeType const& type = dynamic_cast(*_functionCall.expression().annotation().type); auto const& structType = dynamic_cast(*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) @@ -1069,7 +1068,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) case FunctionType::Kind::Error: { _functionCall.expression().accept(*this); - vector argumentTypes; + std::vector argumentTypes; for (ASTPointer const& arg: _functionCall.sortedArguments()) { arg->accept(*this); @@ -1160,15 +1159,15 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) case FunctionType::Kind::TotalAcquiredResource: { _functionCall.expression().accept(*this); - static map const contractAddresses{ + static std::map const contractAddresses{ {FunctionType::Kind::ECRecover, 0x1}, {FunctionType::Kind::SHA256, 0x2}, {FunctionType::Kind::RIPEMD160, 0x3}, {FunctionType::Kind::BatchValidateSign, 0x9}, - {FunctionType::Kind::ValidateMultiSign, 0xa}, - {FunctionType::Kind::VerifyMintProof, 0x1000001}, - {FunctionType::Kind::VerifyTransferProof, 0x1000002}, - {FunctionType::Kind::VerifyBurnProof, 0x1000003}, + {FunctionType::Kind::ValidateMultiSign, 0xa}, + {FunctionType::Kind::VerifyMintProof, 0x1000001}, + {FunctionType::Kind::VerifyTransferProof, 0x1000002}, + {FunctionType::Kind::VerifyBurnProof, 0x1000003}, {FunctionType::Kind::PedersenHash, 0x1000004}, {FunctionType::Kind::RewardBalance, 0x1000005}, {FunctionType::Kind::IsSrCandidate, 0x1000006}, @@ -1274,8 +1273,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) case FunctionType::Kind::BytesConcat: { _functionCall.expression().accept(*this); - vector argumentTypes; - vector targetTypes; + std::vector argumentTypes; + std::vector targetTypes; for (auto const& argument: arguments) { argument->accept(*this); @@ -1539,7 +1538,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) // stack: // 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) @@ -1709,7 +1708,7 @@ bool ExpressionCompiler::visit(FunctionCallOptions const& _functionCallOptions) // Desired Stack: [salt], [gas], [value] enum Option { Salt, Gas, Value }; - vector