Merge pull request #15 from ethereum/develop

Updates
This commit is contained in:
Andy 2023-07-15 17:05:31 -06:00 committed by GitHub
commit a66babed58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
70 changed files with 2506 additions and 1070 deletions

View File

@ -88,6 +88,7 @@ commands:
steps: steps:
- run: - run:
name: Generate bytecode reports for the selected preset name: Generate bytecode reports for the selected preset
no_output_timeout: 30m
command: | command: |
.circleci/parallel_bytecode_report.sh \ .circleci/parallel_bytecode_report.sh \
"<< parameters.label >>" \ "<< parameters.label >>" \
@ -227,6 +228,8 @@ defaults:
PRESETS: PRESETS:
legacy-optimize legacy-optimize
legacy-no-optimize legacy-no-optimize
via-ir-optimize
via-ir-no-optimize
- bytecode_compare_preset_matrix: &bytecode_compare_preset_matrix - bytecode_compare_preset_matrix: &bytecode_compare_preset_matrix
parameters: parameters:
@ -234,6 +237,8 @@ defaults:
# NOTE: Keep in sync with preset list in bytecode_compare_env_presets # NOTE: Keep in sync with preset list in bytecode_compare_env_presets
- legacy-optimize - legacy-optimize
- legacy-no-optimize - legacy-no-optimize
- via-ir-optimize
- via-ir-no-optimize
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Artifacts Templates # Artifacts Templates

View File

@ -44,6 +44,9 @@ cd test-cases/
echo "Preparing input files" echo "Preparing input files"
python3 ../scripts/isolate_tests.py ../test/ python3 ../scripts/isolate_tests.py ../test/
# FIXME: These cases crash because of https://github.com/ethereum/solidity/issues/13583
rm ./*_bytecode_too_large_*.sol ./*_combined_too_large_*.sol
if [[ $binary_type == native ]]; then if [[ $binary_type == native ]]; then
interface=$(echo -e "standard-json\ncli" | circleci tests split) interface=$(echo -e "standard-json\ncli" | circleci tests split)
echo "Selected interface: ${interface}" echo "Selected interface: ${interface}"

View File

@ -17,6 +17,7 @@ Compiler Features:
Bugfixes: Bugfixes:
* Code Generator: Fix not entirely deterministic order of functions in unoptimized Yul output. The choice of C++ compiler in some cases would result in different (but equivalent) bytecode (especially from native binaries vs emscripten binaries)
* Commandline Interface: Fix internal error when using ``--stop-after parsing`` and requesting some of the outputs that require full analysis or compilation. * Commandline Interface: Fix internal error when using ``--stop-after parsing`` and requesting some of the outputs that require full analysis or compilation.
* Commandline Interface: It is no longer possible to specify both ``--optimize-yul`` and ``--no-optimize-yul`` at the same time. * Commandline Interface: It is no longer possible to specify both ``--optimize-yul`` and ``--no-optimize-yul`` at the same time.
* SMTChecker: Fix encoding of side-effects inside ``if`` and ``ternary conditional``statements in the BMC engine. * SMTChecker: Fix encoding of side-effects inside ``if`` and ``ternary conditional``statements in the BMC engine.

23
docs/README.md Normal file
View File

@ -0,0 +1,23 @@
# Solidity Language Docs
## Local environment setup
1. Install python https://www.python.org/downloads/
1. Install sphinx (the tool used to generate the docs) https://www.sphinx-doc.org/en/master/usage/installation.html
Go to `/docs` and run `./docs.sh` to install dependencies and build the project:
```sh
cd docs
./docs.sh
```
That will output the generated htmls under _build/
## Serve environment
```py
python3 -m http.server -d _build/html --cgi 8080
```
Visit dev server at http://localhost:8080

595
docs/_static/css/custom-dark.css vendored Normal file
View File

@ -0,0 +1,595 @@
/* DARK MODE STYLING */
/* code directives */
:root[style*=dark] .method dt,
:root[style*=dark] .class dt,
:root[style*=dark] .data dt,
:root[style*=dark] .attribute dt,
:root[style*=dark] .function dt,
:root[style*=dark] .classmethod dt,
:root[style*=dark] .exception dt,
:root[style*=dark] .descclassname,
:root[style*=dark] .descname {
background-color: #2d2d2d !important;
}
:root[style*=dark] .rst-content dl:not(.docutils) dt {
background-color: #0008;
border-top: solid 3px #fff2;
border-left: solid 3px #fff2;
}
:root[style*=dark] em.property {
color: #888888;
}
/* tables */
:root[style*=dark] .rst-content table.docutils td {
border: 0px;
}
:root[style*=dark] .rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td {
background-color: #0002;
}
:root[style*=dark] .rst-content pre {
background: none;
}
/* inlined code highlights */
:root[style*=dark] .xref,
:root[style*=dark] .py-meth {
color: #aaddff !important;
font-weight: normal !important;
}
/* highlight color search text */
:root[style*=dark] .rst-content .highlighted {
background: #ff5722;
box-shadow: 0 0 0 2px #f0978b;
}
/* notes, warnings, hints */
:root[style*=dark] .hint .admonition-title {
background: #2aa87c !important;
}
:root[style*=dark] .warning .admonition-title {
background: #cc4444 !important;
}
:root[style*=dark] .admonition-title {
background: #3a7ca8 !important;
}
:root[style*=dark] .admonition,
:root[style*=dark] .note {
background-color: #0008 !important;
}
/* table of contents */
:root[style*=dark] .sidebar {
background-color: #191919 !important;
}
:root[style*=dark] .sidebar-title {
background-color: #2b2b2b !important;
}
:root[style*=dark] .wy-menu-vertical code.docutils.literal.notranslate {
background: none !important;
border: none !important;
}
:root[style*=dark] .toc-backref {
color: grey !important;
}
:root[style*=dark] .highlight {
background: #0008;
color: #f8f8f2
}
:root[style*=dark] .highlight .c {
color: #888
}
/* Comment */
:root[style*=dark] .highlight .err {
color: #960050;
background-color: #1e0010
}
/* Error */
:root[style*=dark] .highlight .k {
color: #66d9ef
}
/* Keyword */
:root[style*=dark] .highlight .l {
color: #ae81ff
}
/* Literal */
:root[style*=dark] .highlight .n {
color: #f8f8f2
}
/* Name */
:root[style*=dark] .highlight .o {
color: #f92672
}
/* Operator */
:root[style*=dark] .highlight .p {
color: #f8f8f2
}
/* Punctuation */
:root[style*=dark] .highlight .ch {
color: #888
}
/* Comment.Hashbang */
:root[style*=dark] .highlight .cm {
color: #888
}
/* Comment.Multiline */
:root[style*=dark] .highlight .cp {
color: #888
}
/* Comment.Preproc */
:root[style*=dark] .highlight .cpf {
color: #888
}
/* Comment.PreprocFile */
:root[style*=dark] .highlight .c1 {
color: #888
}
/* Comment.Single */
:root[style*=dark] .highlight .cs {
color: #888
}
/* Comment.Special */
:root[style*=dark] .highlight .gd {
color: #f92672
}
/* Generic.Deleted */
:root[style*=dark] .highlight .ge {
font-style: italic
}
/* Generic.Emph */
:root[style*=dark] .highlight .gi {
color: #a6e22e
}
/* Generic.Inserted */
:root[style*=dark] .highlight .gs {
font-weight: bold
}
/* Generic.Strong */
:root[style*=dark] .highlight .gu {
color: #888
}
/* Generic.Subheading */
:root[style*=dark] .highlight .kc {
color: #66d9ef
}
/* Keyword.Constant */
:root[style*=dark] .highlight .kd {
color: #66d9ef
}
/* Keyword.Declaration */
:root[style*=dark] .highlight .kn {
color: #f92672
}
/* Keyword.Namespace */
:root[style*=dark] .highlight .kp {
color: #66d9ef
}
/* Keyword.Pseudo */
:root[style*=dark] .highlight .kr {
color: #66d9ef
}
/* Keyword.Reserved */
:root[style*=dark] .highlight .kt {
color: #66d9ef
}
/* Keyword.Type */
:root[style*=dark] .highlight .ld {
color: #e6db74
}
/* Literal.Date */
:root[style*=dark] .highlight .m {
color: #ae81ff
}
/* Literal.Number */
:root[style*=dark] .highlight .s {
color: #e6db74
}
/* Literal.String */
:root[style*=dark] .highlight .na {
color: #a6e22e
}
/* Name.Attribute */
:root[style*=dark] .highlight .nb {
color: #f8f8f2
}
/* Name.Builtin */
:root[style*=dark] .highlight .nc {
color: #a6e22e
}
/* Name.Class */
:root[style*=dark] .highlight .no {
color: #66d9ef
}
/* Name.Constant */
:root[style*=dark] .highlight .nd {
color: #a6e22e
}
/* Name.Decorator */
:root[style*=dark] .highlight .ni {
color: #f8f8f2
}
/* Name.Entity */
:root[style*=dark] .highlight .ne {
color: #a6e22e
}
/* Name.Exception */
:root[style*=dark] .highlight .nf {
color: #a6e22e
}
/* Name.Function */
:root[style*=dark] .highlight .nl {
color: #f8f8f2
}
/* Name.Label */
:root[style*=dark] .highlight .nn {
color: #f8f8f2
}
/* Name.Namespace */
:root[style*=dark] .highlight .nx {
color: #a6e22e
}
/* Name.Other */
:root[style*=dark] .highlight .py {
color: #f8f8f2
}
/* Name.Property */
:root[style*=dark] .highlight .nt {
color: #f92672
}
/* Name.Tag */
:root[style*=dark] .highlight .nv {
color: #f8f8f2
}
/* Name.Variable */
:root[style*=dark] .highlight .ow {
color: #f92672
}
/* Operator.Word */
:root[style*=dark] .highlight .w {
color: #f8f8f2
}
/* Text.Whitespace */
:root[style*=dark] .highlight .mb {
color: #ae81ff
}
/* Literal.Number.Bin */
:root[style*=dark] .highlight .mf {
color: #ae81ff
}
/* Literal.Number.Float */
:root[style*=dark] .highlight .mh {
color: #ae81ff
}
/* Literal.Number.Hex */
:root[style*=dark] .highlight .mi {
color: #ae81ff
}
/* Literal.Number.Integer */
:root[style*=dark] .highlight .mo {
color: #ae81ff
}
/* Literal.Number.Oct */
:root[style*=dark] .highlight .sa {
color: #e6db74
}
/* Literal.String.Affix */
:root[style*=dark] .highlight .sb {
color: #e6db74
}
/* Literal.String.Backtick */
:root[style*=dark] .highlight .sc {
color: #e6db74
}
/* Literal.String.Char */
:root[style*=dark] .highlight .dl {
color: #e6db74
}
/* Literal.String.Delimiter */
:root[style*=dark] .highlight .sd {
color: #e6db74
}
/* Literal.String.Doc */
:root[style*=dark] .highlight .s2 {
color: #e6db74
}
/* Literal.String.Double */
:root[style*=dark] .highlight .se {
color: #ae81ff
}
/* Literal.String.Escape */
:root[style*=dark] .highlight .sh {
color: #e6db74
}
/* Literal.String.Heredoc */
:root[style*=dark] .highlight .si {
color: #e6db74
}
/* Literal.String.Interpol */
:root[style*=dark] .highlight .sx {
color: #e6db74
}
/* Literal.String.Other */
:root[style*=dark] .highlight .sr {
color: #e6db74
}
/* Literal.String.Regex */
:root[style*=dark] .highlight .s1 {
color: #e6db74
}
/* Literal.String.Single */
:root[style*=dark] .highlight .ss {
color: #e6db74
}
/* Literal.String.Symbol */
:root[style*=dark] .highlight .bp {
color: #f8f8f2
}
/* Name.Builtin.Pseudo */
:root[style*=dark] .highlight .fm {
color: #a6e22e
}
/* Name.Function.Magic */
:root[style*=dark] .highlight .vc {
color: #f8f8f2
}
/* Name.Variable.Class */
:root[style*=dark] .highlight .vg {
color: #f8f8f2
}
/* Name.Variable.Global */
:root[style*=dark] .highlight .vi {
color: #f8f8f2
}
/* Name.Variable.Instance */
:root[style*=dark] .highlight .vm {
color: #f8f8f2
}
/* Name.Variable.Magic */
:root[style*=dark] .highlight .il {
color: #ae81ff
}
/* Grammar */
:root[style*=dark] .railroad-diagram {
fill: white;
}
:root[style*=dark] .railroad-diagram path {
stroke: white;
}
:root[style*=dark] .railroad-diagram rect {
stroke: white;
}
:root[style*=dark] .a4 .sig-name {
background-color: transparent !important;
}

View File

@ -1,9 +1,166 @@
/* ROOT DECLARATIONS */
:root {
/* Text */
--color-a: #2B247C;
--color-b: #672AC8;
--color-c: #5554D9;
--color-d: #9F94E8;
--color-e: #AEC0F1;
--color-f: #E6E3EC;
/* Background */
--white: #FAF8FF;
--black: #110C4E;
--menu-bg: #2B247C06;
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
--navHeight: 4.5rem;
--sideWidth: 300px;
text-rendering: geometricPrecision;
-webkit-font-smoothing: antialiased;
}
a,
button {
border-radius: 0;
}
:root[style*=dark] {
--color-a: #E6E3EC !important;
--color-b: #AEC0F1 !important;
--color-c: #9F94E8 !important;
--color-d: #5554D9 !important;
--color-e: #672AC8 !important;
--color-f: #2B247C !important;
--white: #110C4E !important;
--black: #FAF8FF !important;
--menu-bg: #E6E3EC06 !important;
}
html,
body,
.unified-header::before,
.wy-nav-side,
.rst-versions,
code,
div,
input[type=text],
a,
.wy-grid-for-nav {
transition: background 150ms ease-in-out;
}
html,
body,
.wy-grid-for-nav {
background-color: var(--color-f) !important;
position: relative;
}
body {
font-family: "Overpass", sans-serif;
}
a {
color: var(--color-c);
}
hr {
margin-block: 2rem;
border-color: var(--color-d) !important;
}
/* HEADER STYLES */
h1 {
font-family: 'Overpass', sans-serif;
font-weight: 700;
font-size: 44px;
color: var(--color-a) !important;
line-height: 1.1;
text-wrap: balance;
margin-top: 4rem;
margin-bottom: 1.5rem;
}
section:first-of-type h1:first-of-type {
font-family: 'Overpass mono', monospace;
font-size: 48px;
margin-top: 3rem;
margin-bottom: 5rem;
}
h2 {
font-family: 'Overpass', sans-serif;
font-weight: 700;
font-size: 38px;
color: var(--color-a) !important;
line-height: 46px;
text-wrap: balance;
margin-top: 4rem;
margin-bottom: 1.5rem;
}
*:not([role=navigation])>p[role=heading]>span,
h3 {
font-family: 'Overpass', sans-serif;
font-weight: 700;
font-size: 32px;
color: var(--color-a) !important;
line-height: 46px;
text-wrap: balance;
margin-top: 4rem;
margin-bottom: 1.5rem;
}
h4 {
font-family: 'Overpass', sans-serif;
font-weight: 700;
font-size: 32px;
color: var(--color-a) !important;
line-height: 46px;
text-wrap: balance;
margin-top: 3rem;
margin-bottom: 1.5rem;
}
h5 {
font-family: 'Overpass', sans-serif;
font-weight: 700;
font-size: 18px;
color: var(--color-a) !important;
line-height: 1.4;
text-wrap: balance;
}
h6 {
font-family: 'Overpass', sans-serif;
font-weight: 700;
font-size: 16px;
color: var(--color-a) !important;
line-height: 1.4;
text-wrap: balance;
}
span.pre,
pre { pre {
white-space: pre-wrap; /* css-3 */ /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ white-space: pre-wrap;
white-space: -pre-wrap; /* Opera 4-6 */ /* Mozilla, since 1999 */
white-space: -o-pre-wrap; /* Opera 7 */ white-space: -moz-pre-wrap;
/* Opera 4-6 */
white-space: -pre-wrap;
/* Opera 7 */
white-space: -o-pre-wrap;
word-wrap: break-word; word-wrap: break-word;
font-family: 'Overpass Mono', monospace;
}
small,
small * {
font-size: 12px;
} }
.wy-table-responsive table td, .wy-table-responsive table td,
@ -16,10 +173,6 @@ pre {
} }
/* links */ /* links */
.rst-content a:not(:visited) {
color: #002fa7;
}
.rst-content .highlighted { .rst-content .highlighted {
background: #eac545; background: #eac545;
} }
@ -29,24 +182,12 @@ pre {
background: #fafafa; background: #fafafa;
} }
.wy-side-nav-search > a img.logo {
width: 100px;
padding: 0;
}
.wy-side-nav-search > a {
padding: 0;
margin: 0;
}
/* project version (displayed under project logo) */ /* project version (displayed under project logo) */
.wy-side-nav-search > div.version { .wy-side-nav-search>div.version {
color: #272525; color: var(--color-b);
} margin-top: 0;
margin-bottom: 0.5rem;
/* menu section headers */ text-align: start;
.wy-menu p.caption {
color: #65afff;
} }
/* Link to Remix IDE shown next to code snippets */ /* Link to Remix IDE shown next to code snippets */
@ -58,18 +199,618 @@ pre {
} }
.rst-content .remix-link-container a.remix-link { .rst-content .remix-link-container a.remix-link {
display: inline-block;
font-size: 0.7em; font-size: 0.7em;
padding: 0.1em 0.4em; padding: 0.1em 0.5em;
background: #e1e4e5; background: transparent;
color: #707070; color: var(--color-a) !important;
} border: 1px solid var(--color-a);
text-decoration: none;
.rst-content .remix-link-container a.remix-link:hover {
background: #c8cbcc;
} }
.rst-content div.highlight-solidity, .rst-content div.highlight-solidity,
.rst-content div.highlight-yul { .rst-content div.highlight-yul {
margin-top: 0; margin-top: 0;
} }
/* CUSTOMIZATION UPDATES */
.wy-nav-content-wrap,
.wy-nav-content {
background: transparent !important;
}
.wy-side-nav-search {
background-color: transparent !important;
color: var(--color-a) !important;
box-shadow: 0 4 4 0 var(--color-a);
border-bottom: 1px solid var(--color-d) !important;
}
.wy-side-nav-search svg {
color: var(--color-a) !important;
}
.wy-nav-top {
background-color: transparent !important;
color: var(--color-a) !important;
}
.wy-nav-top a {
color: var(--color-a) !important;
}
.wy-breadcrumbs a.icon-home:before {
content: "Documentation";
font-family: "Overpass", sans-serif;
}
.rst-content table.docutils thead {
color: var(--color-a);
}
code.docutils.literal.notranslate {
padding: 2px 4px;
font-size: 0.875em;
font-family: "Overpass Mono", monospace;
background: var(--white);
color: var(--color-c);
border: 0px;
}
dt code.docutils.literal.notranslate {
background: none;
}
.wy-nav-content {
color: var(--color-a);
}
/* .rst-content a:not(:visited) { */
/* color: var(--color-b) !important; */
/* } */
.rst-content a:visited {
color: var(--color-c) !important;
}
.rst-content a {
text-decoration: underline;
}
.rst-content a:where(:focus, :focus-visible, :hover) {
color: var(--color-d) !important;
}
.wy-side-scroll a {
color: var(--color-a);
background: transparent;
font-size: 1rem;
line-height: 125%;
}
.wy-menu-vertical li.current a,
.wy-menu-vertical li.current li a,
.wy-menu-vertical li.current li a code {
border: none;
color: var(--color-a);
}
ul.current ul,
.wy-menu-vertical li.current a:hover,
.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,
.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,
.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,
.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,
.wy-menu-vertical li.current {
background: var(--menu-bg) !important;
}
.wy-menu.wy-menu-vertical>ul {
margin-bottom: 3rem;
}
.wy-menu.wy-menu-vertical>p {
color: var(--color-c);
}
.wy-menu-vertical li.on a,
.wy-menu-vertical li.current>a {
background: var(--menu-bg) !important;
border-bottom: 0px !important;
border-top: 0px !important;
}
.btn {
border-radius: 0;
text-decoration: none !important;
}
.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),
a.btn.btn-neutral:visited,
a.btn.btn-neutral:not(:visited),
a.btn.btn-neutral {
background: transparent !important;
color: var(--color-a) !important;
border: 2px solid var(--color-a) !important;
text-decoration: none;
}
.rst-content .remix-link-container a.remix-link:hover,
.wy-breadcrumbs-aside a:hover,
a.fa.fa-github:hover,
a.btn.btn-neutral:hover {
background: var(--white) !important;
color: var(--color-b) !important;
border-color: var(--color-b) !important;
}
footer .rst-footer-buttons {
display: flex;
justify-content: center;
gap: 2rem;
}
/**
* Customization for the unified layout
*/
/* Site wrapper, and two children: header and rest */
.unified-wrapper {
position: fixed;
inset: 0;
top: var(--navHeight);
max-width: 80rem;
margin-inline: auto;
}
/* Site header */
.unified-header {
position: fixed;
top: 0;
inset-inline: 0;
z-index: 99999;
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;
align-items: center;
justify-content: space-between;
padding-inline: 2rem;
padding-block: 1rem;
}
.unified-header::before {
content: "";
position: absolute;
inset: 0;
opacity: 95%;
background: var(--color-f);
z-index: -1;
}
.unified-header .home-link {
display: block;
text-decoration: none;
width: 25px;
height: 40px;
}
.unified-header .home-link:hover .solidity-logo {
transform: scale(1.1);
transition: transform 100ms ease-in-out;
}
.unified-header img.solidity-logo {
transform: scale(1);
transition: transform 100ms ease-in-out;
width: 100%;
height: 100%;
}
.unified-header .nav-bar {
display: flex;
align-items: center;
justify-content: flex-end;
}
.unified-header .nav-bar .nav-button-container {
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
}
.unified-header .nav-link {
display: inline-block;
padding-inline: 8px;
padding-block: 4px;
font-size: 14px;
font-family: 'Overpass Mono', monospace;
text-decoration: none;
color: var(--color-a);
letter-spacing: -0.02em;
font-weight: 400;
box-sizing: content-box;
border-bottom: 1px solid transparent;
}
.unified-header .nav-link.active {
background: var(--white);
}
.unified-header .nav-link:hover {
color: var(--color-c);
border-bottom: 1px solid var(--color-c);
}
/* Rest: Grid, 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;
}
/* First child: Side bar */
.unified-wrapper .wy-grid-for-nav nav.wy-nav-side {
position: relative;
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;
}
.unified-wrapper .wy-grid-for-nav nav.wy-nav-side .wy-side-scroll {
position: relative !important;
width: fit-content !important;
height: unset !important;
}
.unified-wrapper .wy-grid-for-nav nav.wy-nav-side .wy-side-scroll .wy-side-nav-search {
margin: 0 !important;
width: var(--sideWidth) !important;
}
.wy-nav-side,
.wy-side-scroll,
.wy-side-nav-search,
.my-menu {
width: 100% !important;
}
.wy-nav-side input[type=text] {
font-family: "Overpass", sans-serif;
border-radius: 0;
border-color: var(--color-d);
background: var(--white);
box-shadow: none;
color: var(--color-a);
}
.wy-nav-side input[type=text]::placeholder {
font-family: "Overpass", sans-serif;
color: var(--color-e);
font-size: 16px;
position: relative;
top: 4px;
}
/* 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;
}
.unified-wrapper .wy-grid-for-nav .wy-nav-content .rst-content {
max-width: 70ch;
margin-inline: auto;
}
.unified-wrapper.menu-open .backdrop {
opacity: 0.5;
}
.unified-wrapper .wy-nav-side,
.unified-wrapper .rst-versions {
left: auto;
}
.unified-wrapper .backdrop {
opacity: 0;
transition: opacity 200ms ease-in-out;
}
@media (max-width: 768px) {
h2 {
margin-top: 3rem;
margin-bottom: 1rem;
}
h3 {
margin-top: 3rem;
margin-bottom: 1rem;
}
h4 {
margin-top: 2rem;
margin-bottom: 1rem;
}
/* Menu closed styles */
.unified-header .nav-link {
display: none;
}
.unified-header .inner-header {
padding-inline: 1rem;
}
.unified-wrapper .wy-grid-for-nav {
grid-template-columns: 1fr;
}
.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;
}
.unified-wrapper.menu-open .rst-versions {
position: sticky;
bottom: 0;
width: 100%;
}
.unified-wrapper.menu-open .backdrop {
display: block;
position: fixed;
inset: 0;
opacity: 1;
transition: opacity 200ms ease-in-out;
z-index: 5;
background: #0006;
}
a.skip-to-content {
display: none;
}
}
ul.search .context {
color: var(--color-a) !important;
}
.rst-versions {
background: var(--color-f);
}
.rst-versions.shift-up {
height: unset !important;
max-height: unset !important;
overflow-y: unset !important;
}
.rst-content dl:not(.docutils) dt {
color: var(--color-a);
background-color: #fff8;
border-top: solid 3px #0002;
border-inline-start: solid 3px #0002;
padding: 2px 6px;
}
.rst-versions .rst-current-version {
border-color: var(--color-d) !important;
}
.rst-current-version *,
.rst-current-version .fa:before,
.rst-current-version .fa-element {
color: var(--color-b) !important;
}
.rst-current-version dt,
.rst-current-version dd,
.rst-current-version dd a,
.rst-other-versions dl:last-of-type dt,
.rst-other-versions dl:last-of-type dd,
.rst-other-versions dl:last-of-type dd a {
font-size: 14px !important;
}
.rst-other-versions {
background: var(--white) !important;
color: var(--color-a) !important;
}
.rst-other-versions a {
text-decoration: underline;
color: var(--color-c) !important;
}
.rst-other-versions dt {
color: var(--color-a) !important;
}
.rst-other-versions dl {
margin-bottom: 1.5rem !important;
}
.rst-other-versions dl:last-of-type {
margin-top: 2rem !important;
}
/* Bottom Search */
.wy-nav-side input[type=text],
.rst-other-versions dl:last-of-type dd {
width: 100%;
}
.rst-other-versions dl:last-of-type dt {
color: var(--color-b) !important;
}
.rst-other-versions dl:last-of-type div[style*=padding],
.rst-other-versions dl dd:first-of-type a {
padding-inline-start: 0 !important;
}
button.toctree-expand {
color: var(--black) !important;
}
/* Light/dark color mode toggle 🌓 */
button.color-toggle {
display: inline-flex;
appearance: none;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: center;
justify-content: center;
user-select: none;
outline: none;
height: 28px;
width: 28px;
background: none;
border: none;
padding: 6px;
margin: 6px;
transition-duration: 200ms;
transition-property: background-color,
color,
fill,
stroke,
opacity;
}
button.color-toggle:focus-visible {
outline: 2px solid var(--color-c);
color: var(--color-c);
}
button.color-toggle:hover {
color: var(--color-c);
background: #0002;
}
button.color-toggle .color-toggle-icon {
width: 100%;
height: 100%;
margin: 0;
display: inline-block;
line-height: 1em;
-webkit-flex-shrink: 0;
-ms-flex-negative: 0;
flex-shrink: 0;
vertical-align: middle;
/* color: var(--color-a); */
}
button.mobile-menu-button {
display: none;
}
@media (max-width: 768px) {
nav.wy-nav-top {
display: none;
}
button.mobile-menu-button {
display: flex;
}
}
.hidden {
display: none;
}
#search-results .search li:first-child,
#search-results .search li {
border-color: var(--color-d);
}
#search-results .search li:last-child {
border: 0px;
}
.forum-link::after {
content: ' ↗';
font-size: 14px;
font-family: 'Overpass Mono', monospace;
}
.wy-breadcrumbs-aside {
display: block;
padding-top: 0;
}
.wy-breadcrumbs-aside a {
padding: 0.5rem 0.75rem;
font-size: 12px;
font-family: "'Overpass'", sans-serif;
font-weight: 700;
}
a.skip-to-content:visited,
a.skip-to-content:not(:visited),
a.skip-to-content {
display: block;
pointer-events: none;
width: fit-content;
opacity: 0;
transition: opacity 200ms ease-in-out;
padding: 2px 4px;
font-size: 14px;
margin-inline-end: auto;
margin-inline-start: 2rem;
color: var(--color-a);
}
a.skip-to-content:focus {
opacity: 1;
transition: opacity 200ms ease-in-out;
}
#content {
scroll-margin-top: 6rem;
scroll-behavior: smooth;
}

View File

@ -1,652 +0,0 @@
/* links */
.rst-content a:not(:visited) {
color: #aaddff;
}
/* code directives */
.method dt,
.class dt,
.data dt,
.attribute dt,
.function dt,
.classmethod dt,
.exception dt,
.descclassname,
.descname {
background-color: #2d2d2d !important;
}
.rst-content dl:not(.docutils) dt {
color: #aaddff;
background-color: #2d2d2d;
border-top: solid 3px #525252;
border-left: solid 3px #525252;
}
em.property {
color: #888888;
}
/* tables */
.rst-content table.docutils thead {
color: #ddd;
}
.rst-content table.docutils td {
border: 0px;
}
.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td {
background-color: #5a5a5a;
}
.rst-content pre {
background: none;
}
/* inlined code highlights */
.xref,
.py-meth,
.rst-content a code {
color: #aaddff !important;
font-weight: normal !important;
}
.rst-content code {
color: #eee !important;
font-weight: normal !important;
}
code.literal {
background-color: #2d2d2d !important;
border: 1px solid #6d6d6d !important;
}
code.docutils.literal.notranslate {
color: #ddd;
}
/* highlight color search text */
.rst-content .highlighted {
background: #ff5722;
box-shadow: 0 0 0 2px #f0978b;
}
/* notes, warnings, hints */
.hint .admonition-title {
background: #2aa87c !important;
}
.warning .admonition-title {
background: #cc4444 !important;
}
.admonition-title {
background: #3a7ca8 !important;
}
.admonition,
.note {
background-color: #2d2d2d !important;
}
/* table of contents */
.wy-nav-content-wrap {
background-color: rgba(0, 0, 0, 0.6) !important;
}
.sidebar {
background-color: #191919 !important;
}
.sidebar-title {
background-color: #2b2b2b !important;
}
.wy-menu-vertical a {
color: #ddd;
}
.wy-menu-vertical code.docutils.literal.notranslate {
color: #404040;
background: none !important;
border: none !important;
}
.wy-nav-content {
background: #3c3c3c;
color: #dddddd;
}
.wy-menu-vertical li.on a,
.wy-menu-vertical li.current>a {
background: #a3a3a3;
border-bottom: 0px !important;
border-top: 0px !important;
}
.wy-menu-vertical li.current {
background: #b3b3b3;
}
.toc-backref {
color: grey !important;
}
.highlight .hll {
background-color: #49483e
}
.highlight {
background: #222;
color: #f8f8f2
}
.highlight .c {
color: #888
}
/* Comment */
.highlight .err {
color: #960050;
background-color: #1e0010
}
/* Error */
.highlight .k {
color: #66d9ef
}
/* Keyword */
.highlight .l {
color: #ae81ff
}
/* Literal */
.highlight .n {
color: #f8f8f2
}
/* Name */
.highlight .o {
color: #f92672
}
/* Operator */
.highlight .p {
color: #f8f8f2
}
/* Punctuation */
.highlight .ch {
color: #888
}
/* Comment.Hashbang */
.highlight .cm {
color: #888
}
/* Comment.Multiline */
.highlight .cp {
color: #888
}
/* Comment.Preproc */
.highlight .cpf {
color: #888
}
/* Comment.PreprocFile */
.highlight .c1 {
color: #888
}
/* Comment.Single */
.highlight .cs {
color: #888
}
/* Comment.Special */
.highlight .gd {
color: #f92672
}
/* Generic.Deleted */
.highlight .ge {
font-style: italic
}
/* Generic.Emph */
.highlight .gi {
color: #a6e22e
}
/* Generic.Inserted */
.highlight .gs {
font-weight: bold
}
/* Generic.Strong */
.highlight .gu {
color: #888
}
/* Generic.Subheading */
.highlight .kc {
color: #66d9ef
}
/* Keyword.Constant */
.highlight .kd {
color: #66d9ef
}
/* Keyword.Declaration */
.highlight .kn {
color: #f92672
}
/* Keyword.Namespace */
.highlight .kp {
color: #66d9ef
}
/* Keyword.Pseudo */
.highlight .kr {
color: #66d9ef
}
/* Keyword.Reserved */
.highlight .kt {
color: #66d9ef
}
/* Keyword.Type */
.highlight .ld {
color: #e6db74
}
/* Literal.Date */
.highlight .m {
color: #ae81ff
}
/* Literal.Number */
.highlight .s {
color: #e6db74
}
/* Literal.String */
.highlight .na {
color: #a6e22e
}
/* Name.Attribute */
.highlight .nb {
color: #f8f8f2
}
/* Name.Builtin */
.highlight .nc {
color: #a6e22e
}
/* Name.Class */
.highlight .no {
color: #66d9ef
}
/* Name.Constant */
.highlight .nd {
color: #a6e22e
}
/* Name.Decorator */
.highlight .ni {
color: #f8f8f2
}
/* Name.Entity */
.highlight .ne {
color: #a6e22e
}
/* Name.Exception */
.highlight .nf {
color: #a6e22e
}
/* Name.Function */
.highlight .nl {
color: #f8f8f2
}
/* Name.Label */
.highlight .nn {
color: #f8f8f2
}
/* Name.Namespace */
.highlight .nx {
color: #a6e22e
}
/* Name.Other */
.highlight .py {
color: #f8f8f2
}
/* Name.Property */
.highlight .nt {
color: #f92672
}
/* Name.Tag */
.highlight .nv {
color: #f8f8f2
}
/* Name.Variable */
.highlight .ow {
color: #f92672
}
/* Operator.Word */
.highlight .w {
color: #f8f8f2
}
/* Text.Whitespace */
.highlight .mb {
color: #ae81ff
}
/* Literal.Number.Bin */
.highlight .mf {
color: #ae81ff
}
/* Literal.Number.Float */
.highlight .mh {
color: #ae81ff
}
/* Literal.Number.Hex */
.highlight .mi {
color: #ae81ff
}
/* Literal.Number.Integer */
.highlight .mo {
color: #ae81ff
}
/* Literal.Number.Oct */
.highlight .sa {
color: #e6db74
}
/* Literal.String.Affix */
.highlight .sb {
color: #e6db74
}
/* Literal.String.Backtick */
.highlight .sc {
color: #e6db74
}
/* Literal.String.Char */
.highlight .dl {
color: #e6db74
}
/* Literal.String.Delimiter */
.highlight .sd {
color: #e6db74
}
/* Literal.String.Doc */
.highlight .s2 {
color: #e6db74
}
/* Literal.String.Double */
.highlight .se {
color: #ae81ff
}
/* Literal.String.Escape */
.highlight .sh {
color: #e6db74
}
/* Literal.String.Heredoc */
.highlight .si {
color: #e6db74
}
/* Literal.String.Interpol */
.highlight .sx {
color: #e6db74
}
/* Literal.String.Other */
.highlight .sr {
color: #e6db74
}
/* Literal.String.Regex */
.highlight .s1 {
color: #e6db74
}
/* Literal.String.Single */
.highlight .ss {
color: #e6db74
}
/* Literal.String.Symbol */
.highlight .bp {
color: #f8f8f2
}
/* Name.Builtin.Pseudo */
.highlight .fm {
color: #a6e22e
}
/* Name.Function.Magic */
.highlight .vc {
color: #f8f8f2
}
/* Name.Variable.Class */
.highlight .vg {
color: #f8f8f2
}
/* Name.Variable.Global */
.highlight .vi {
color: #f8f8f2
}
/* Name.Variable.Instance */
.highlight .vm {
color: #f8f8f2
}
/* Name.Variable.Magic */
.highlight .il {
color: #ae81ff
}
/* Link to Remix IDE shown over code snippets */
.rst-content .remix-link-container a.remix-link {
color: black;
}
/* Grammar */
.railroad-diagram {
fill: white;
}
.railroad-diagram path {
stroke: white;
}
.railroad-diagram rect {
stroke: white;
}
.a4 .sig-name {
background-color: transparent !important;
}

2
docs/_static/css/fonts.css vendored Normal file
View File

@ -0,0 +1,2 @@
@import url("https://fonts.cdnfonts.com/css/overpass");
@import url("https://fonts.cdnfonts.com/css/overpass-mono");

399
docs/_static/css/pygments.css vendored Normal file
View File

@ -0,0 +1,399 @@
pre {
line-height: 125%;
}
td.linenos .normal {
color: inherit;
background-color: transparent;
padding-left: 5px;
padding-right: 5px;
}
span.linenos {
color: inherit;
background-color: transparent;
padding-left: 5px;
padding-right: 5px;
}
td.linenos .special {
color: #000000;
background-color: #ffffc0;
padding-left: 5px;
padding-right: 5px;
}
span.linenos.special {
color: #000000;
background-color: #ffffc0;
padding-left: 5px;
padding-right: 5px;
}
.highlight .hll {
background-color: #ffffcc
}
.highlight {
background: #eeffcc;
}
.highlight .c {
color: #408090;
font-style: italic
}
/* Comment */
.highlight .err {
border: 1px solid #FF0000
}
/* Error */
.highlight .k {
color: #007020;
font-weight: bold
}
/* Keyword */
.highlight .o {
color: #666666
}
/* Operator */
.highlight .ch {
color: #408090;
font-style: italic
}
/* Comment.Hashbang */
.highlight .cm {
color: #408090;
font-style: italic
}
/* Comment.Multiline */
.highlight .cp {
color: #007020
}
/* Comment.Preproc */
.highlight .cpf {
color: #408090;
font-style: italic
}
/* Comment.PreprocFile */
.highlight .c1 {
color: #408090;
font-style: italic
}
/* Comment.Single */
.highlight .cs {
color: #408090;
background-color: #fff0f0
}
/* Comment.Special */
.highlight .gd {
color: #A00000
}
/* Generic.Deleted */
.highlight .ge {
font-style: italic
}
/* Generic.Emph */
.highlight .gr {
color: #FF0000
}
/* Generic.Error */
.highlight .gh {
color: #000080;
font-weight: bold
}
/* Generic.Heading */
.highlight .gi {
color: #00A000
}
/* Generic.Inserted */
.highlight .go {
color: #333333
}
/* Generic.Output */
.highlight .gp {
color: #c65d09;
font-weight: bold
}
/* Generic.Prompt */
.highlight .gs {
font-weight: bold
}
/* Generic.Strong */
.highlight .gu {
color: #800080;
font-weight: bold
}
/* Generic.Subheading */
.highlight .gt {
color: #0044DD
}
/* Generic.Traceback */
.highlight .kc {
color: #007020;
font-weight: bold
}
/* Keyword.Constant */
.highlight .kd {
color: #007020;
font-weight: bold
}
/* Keyword.Declaration */
.highlight .kn {
color: #007020;
font-weight: bold
}
/* Keyword.Namespace */
.highlight .kp {
color: #007020
}
/* Keyword.Pseudo */
.highlight .kr {
color: #007020;
font-weight: bold
}
/* Keyword.Reserved */
.highlight .kt {
color: #902000
}
/* Keyword.Type */
.highlight .m {
color: #208050
}
/* Literal.Number */
.highlight .s {
color: #4070a0
}
/* Literal.String */
.highlight .na {
color: #4070a0
}
/* Name.Attribute */
.highlight .nb {
color: #007020
}
/* Name.Builtin */
.highlight .nc {
color: #0e84b5;
font-weight: bold
}
/* Name.Class */
.highlight .no {
color: #60add5
}
/* Name.Constant */
.highlight .nd {
color: #555555;
font-weight: bold
}
/* Name.Decorator */
.highlight .ni {
color: #d55537;
font-weight: bold
}
/* Name.Entity */
.highlight .ne {
color: #007020
}
/* Name.Exception */
.highlight .nf {
color: #06287e
}
/* Name.Function */
.highlight .nl {
color: #002070;
font-weight: bold
}
/* Name.Label */
.highlight .nn {
color: #0e84b5;
font-weight: bold
}
/* Name.Namespace */
.highlight .nt {
color: #062873;
font-weight: bold
}
/* Name.Tag */
.highlight .nv {
color: #bb60d5
}
/* Name.Variable */
.highlight .ow {
color: #007020;
font-weight: bold
}
/* Operator.Word */
.highlight .w {
color: #bbbbbb
}
/* Text.Whitespace */
.highlight .mb {
color: #208050
}
/* Literal.Number.Bin */
.highlight .mf {
color: #208050
}
/* Literal.Number.Float */
.highlight .mh {
color: #208050
}
/* Literal.Number.Hex */
.highlight .mi {
color: #208050
}
/* Literal.Number.Integer */
.highlight .mo {
color: #208050
}
/* Literal.Number.Oct */
.highlight .sa {
color: #4070a0
}
/* Literal.String.Affix */
.highlight .sb {
color: #4070a0
}
/* Literal.String.Backtick */
.highlight .sc {
color: #4070a0
}
/* Literal.String.Char */
.highlight .dl {
color: #4070a0
}
/* Literal.String.Delimiter */
.highlight .sd {
color: #4070a0;
font-style: italic
}
/* Literal.String.Doc */
.highlight .s2 {
color: #4070a0
}
/* Literal.String.Double */
.highlight .se {
color: #4070a0;
font-weight: bold
}
/* Literal.String.Escape */
.highlight .sh {
color: #4070a0
}
/* Literal.String.Heredoc */
.highlight .si {
color: #70a0d0;
font-style: italic
}
/* Literal.String.Interpol */
.highlight .sx {
color: #c65d09
}
/* Literal.String.Other */
.highlight .sr {
color: #235388
}
/* Literal.String.Regex */
.highlight .s1 {
color: #4070a0
}
/* Literal.String.Single */
.highlight .ss {
color: #517918
}
/* Literal.String.Symbol */
.highlight .bp {
color: #007020
}
/* Name.Builtin.Pseudo */
.highlight .fm {
color: #06287e
}
/* Name.Function.Magic */
.highlight .vc {
color: #bb60d5
}
/* Name.Variable.Class */
.highlight .vg {
color: #bb60d5
}
/* Name.Variable.Global */
.highlight .vi {
color: #bb60d5
}
/* Name.Variable.Instance */
.highlight .vm {
color: #bb60d5
}
/* Name.Variable.Magic */
.highlight .il {
color: #208050
}
/* Literal.Number.Integer.Long */

View File

@ -9,6 +9,13 @@ input[type=checkbox] {
padding: 10px; padding: 10px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
background-color: var(--color-f);
border-top: 1px solid var(--color-c);
}
.fa-caret-down,
.fa-book {
color: var(--color-a) !important;
} }
.rst-versions .rst-current-version .fa-book, .rst-versions .rst-current-version .fa-book,
@ -76,8 +83,6 @@ html.transition *:after {
transition-delay: 0 !important; transition-delay: 0 !important;
} }
nav.wy-nav-side { .wy-menu-vertical a:hover {
/* The default padding of 2em is too small and the "Keyword Index" link gets obscured background-color: #0002;
* by the version toggle. */ }
padding-bottom: 3em;
}

BIN
docs/_static/fonts/overpass-bold.otf vendored Normal file

Binary file not shown.

BIN
docs/_static/fonts/overpass-bold.woff2 vendored Normal file

Binary file not shown.

BIN
docs/_static/fonts/overpass-italic.otf vendored Normal file

Binary file not shown.

BIN
docs/_static/fonts/overpass-light.otf vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
docs/_static/fonts/overpass-regular.otf vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
docs/_static/fonts/overpass-semibold.otf vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
docs/_static/img/favicon.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

3
docs/_static/img/hamburger-dark.svg vendored Normal file
View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="#E6E3EC" xmlns="http://www.w3.org/2000/svg" focusable="false" class="color-toggle-icon" aria-hidden="true">
<path d="M 3 5 A 1.0001 1.0001 0 1 0 3 7 L 21 7 A 1.0001 1.0001 0 1 0 21 5 L 3 5 z M 3 11 A 1.0001 1.0001 0 1 0 3 13 L 21 13 A 1.0001 1.0001 0 1 0 21 11 L 3 11 z M 3 17 A 1.0001 1.0001 0 1 0 3 19 L 21 19 A 1.0001 1.0001 0 1 0 21 17 L 3 17 z" />
</svg>

After

Width:  |  Height:  |  Size: 413 B

3
docs/_static/img/hamburger-light.svg vendored Normal file
View File

@ -0,0 +1,3 @@
<svg width="24px" height="24px" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" focusable="false" class="color-toggle-icon" aria-hidden="true">
<path fill="#2B247C" d="M 3 5 A 1.0001 1.0001 0 1 0 3 7 L 21 7 A 1.0001 1.0001 0 1 0 21 5 L 3 5 z M 3 11 A 1.0001 1.0001 0 1 0 3 13 L 21 13 A 1.0001 1.0001 0 1 0 21 11 L 3 11 z M 3 17 A 1.0001 1.0001 0 1 0 3 19 L 21 19 A 1.0001 1.0001 0 1 0 21 17 L 3 17 z" />
</svg>

After

Width:  |  Height:  |  Size: 437 B

8
docs/_static/img/logo-dark.svg vendored Normal file
View File

@ -0,0 +1,8 @@
<svg width="100" height="160" viewBox="0 0 100 160" fill="#E6E3EC" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.8" d="M50 44.3013L25 1L0 44.3013L25 87.6025L50 44.3013Z" />
<path opacity="0.45" d="M50 44.3091L75 1.00781L25 1.00781L0 44.3091H50Z" />
<path opacity="0.6" d="M75 1.00781L25 1.00781L50 44.3091H100L75 1.00781Z" />
<path opacity="0.8" d="M50 115.699L75 159L100 115.699L75 72.3975L50 115.699Z" />
<path opacity="0.45" d="M50 115.691L25 158.993H75L100 115.691L50 115.691Z" />
<path opacity="0.6" d="M25 158.993H75L50 115.691L0 115.691L25 158.993Z" />
</svg>

After

Width:  |  Height:  |  Size: 574 B

8
docs/_static/img/logo.svg vendored Normal file
View File

@ -0,0 +1,8 @@
<svg width="100" height="160" viewBox="0 0 100 160" fill="#2B247C" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.8" d="M50 44.3013L25 1L0 44.3013L25 87.6025L50 44.3013Z" />
<path opacity="0.45" d="M50 44.3091L75 1.00781L25 1.00781L0 44.3091H50Z" />
<path opacity="0.6" d="M75 1.00781L25 1.00781L50 44.3091H100L75 1.00781Z" />
<path opacity="0.8" d="M50 115.699L75 159L100 115.699L75 72.3975L50 115.699Z" />
<path opacity="0.45" d="M50 115.691L25 158.993H75L100 115.691L50 115.691Z" />
<path opacity="0.6" d="M25 158.993H75L50 115.691L0 115.691L25 158.993Z" />
</svg>

After

Width:  |  Height:  |  Size: 574 B

3
docs/_static/img/moon.svg vendored Normal file
View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="#2B247C" xmlns="http://www.w3.org/2000/svg" focusable="false" class="color-toggle-icon" aria-hidden="true">
<path d="M21.4,13.7C20.6,13.9,19.8,14,19,14c-5,0-9-4-9-9c0-0.8,0.1-1.6,0.3-2.4c0.1-0.3,0-0.7-0.3-1 c-0.3-0.3-0.6-0.4-1-0.3C4.3,2.7,1,7.1,1,12c0,6.1,4.9,11,11,11c4.9,0,9.3-3.3,10.6-8.1c0.1-0.3,0-0.7-0.3-1 C22.1,13.7,21.7,13.6,21.4,13.7z" />
</svg>

After

Width:  |  Height:  |  Size: 408 B

13
docs/_static/img/sun.svg vendored Normal file
View File

@ -0,0 +1,13 @@
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" focusable="false" class="color-toggle-icon" aria-hidden="true">
<g stroke-linejoin="round" stroke-linecap="round" stroke-width="2" fill="none" stroke="#E6E3EC">
<circle cx="12" cy="12" r="5" />
<path d="M12 1v2" />
<path d="M12 21v2" />
<path d="M4.22 4.22l1.42 1.42" />
<path d="M18.36 18.36l1.42 1.42" />
<path d="M1 12h2" />
<path d="M21 12h2" />
<path d="M4.22 19.78l1.42-1.42" />
<path d="M18.36 5.64l1.42-1.42" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 554 B

31
docs/_static/js/constants.js vendored Normal file
View File

@ -0,0 +1,31 @@
// 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 COLOR_TOGGLE_ICON_CLASS = "color-toggle-icon";
const SOLIDITY_LOGO_CLASS = "solidity-logo";
const LS_COLOR_SCHEME = "color-scheme";
// Solidity navigation constants
const SOLIDITY_HOME_URL = "https://soliditylang.org";
const BLOG_URL = `${SOLIDITY_HOME_URL}/blog`;
const DOCS_URL = "/";
const USE_CASES_PATH = `${SOLIDITY_HOME_URL}/use-cases`;
const CONTRIBUTE_PATH = `/en/latest/contributing.html`;
const ABOUT_PATH = `${SOLIDITY_HOME_URL}/about`;
const FORUM_URL = "https://forum.soliditylang.org/";
const NAV_LINKS = [
{ name: "Blog", href: BLOG_URL },
{ name: "Documentation", href: DOCS_URL },
{ name: "Use cases", href: USE_CASES_PATH },
{ name: "Contribute", href: CONTRIBUTE_PATH },
{ name: "About", href: ABOUT_PATH },
{ name: "Forum", href: FORUM_URL },
];
const MOBILE_MENU_TOGGLE_CLASS = "shift";
const WRAPPER_CLASS = "unified-wrapper";

250
docs/_static/js/initialize.js vendored Normal file
View File

@ -0,0 +1,250 @@
const getLogoSrc = (isDark) => (isDark ? DARK_LOGO_PATH : LIGHT_LOGO_PATH);
const getModeIconSrc = (isDark) => (isDark ? SUN_ICON_PATH : MOON_ICON_PATH);
const getMenuIconSrc = (isDark) =>
isDark ? DARK_HAMBURGER_PATH : LIGHT_HAMBURGER_PATH;
function addFooterNote() {
const contentInfo = document.querySelector("div[role=contentinfo]");
const footerNote = document.createElement("p");
footerNote.classList.add("footer-note");
footerNote.innerHTML =
'Customized with ❤️ by the <a href="https://ethereum.org/" target="_blank">ethereum.org</a> team.';
contentInfo.parentNode.insertBefore(footerNote, contentInfo.nextSibling);
}
function rearrangeDom() {
const bodyDivs = document.querySelectorAll("body>div");
bodyDivs.forEach((div) => div.remove());
const wrapperDiv = document.createElement("div");
wrapperDiv.classList.add(WRAPPER_CLASS);
bodyDivs.forEach((div) => wrapperDiv.appendChild(div));
document.body.prepend(wrapperDiv);
const rstVersions = document.querySelector(".rst-versions");
rstVersions.remove();
const wyNavSide = document.querySelector("nav.wy-nav-side");
wyNavSide.appendChild(rstVersions);
const backdrop = document.createElement("div");
backdrop.classList.add("backdrop");
wrapperDiv.appendChild(backdrop);
const content = document.querySelector(".wy-nav-content");
content.id = "content";
const oldWrap = document.querySelector("section.wy-nav-content-wrap");
oldWrap.remove();
document.querySelector(".wy-grid-for-nav").appendChild(content);
}
function buildHeader() {
const isDarkMode = localStorage.getItem(LS_COLOR_SCHEME) == DARK;
const header = document.createElement("div");
header.classList.add("unified-header");
document.querySelector(`.${WRAPPER_CLASS}`).prepend(header);
const innerHeader = document.createElement("div");
innerHeader.classList.add("inner-header");
header.appendChild(innerHeader);
const homeLink = document.createElement("a");
homeLink.classList.add("home-link");
homeLink.href = SOLIDITY_HOME_URL;
homeLink.ariaLabel = "Solidity home";
innerHeader.appendChild(homeLink);
const logo = document.createElement("img");
logo.classList.add(SOLIDITY_LOGO_CLASS);
logo.src = getLogoSrc(isDarkMode);
logo.alt = "Solidity logo";
homeLink.appendChild(logo);
const skipToContent = document.createElement("a");
skipToContent.classList.add("skip-to-content");
skipToContent.href = "#content";
skipToContent.innerText = "{ skip to content }";
innerHeader.appendChild(skipToContent);
const navBar = document.createElement("nav");
navBar.classList.add("nav-bar");
innerHeader.appendChild(navBar);
const linkElements = NAV_LINKS.map(({ name, href }) => {
const link = document.createElement("a");
link.classList.add("nav-link");
link.setAttribute("key", name);
link.setAttribute("href", href);
link.setAttribute("aria-label", name);
if (href === FORUM_URL) {
link.classList.add("forum-link");
link.setAttribute("target", "_blank");
link.setAttribute("rel", "noopener noreferrer");
}
link.innerText = name;
return link;
});
linkElements.forEach((link) => navBar.appendChild(link));
// Flex wrapper for color mode and mobile menu buttons
const navButtonContainer = document.createElement("div");
navButtonContainer.classList.add("nav-button-container");
navBar.appendChild(navButtonContainer);
// Build color toggle
const toggleIcon = document.createElement("img");
toggleIcon.classList.add(COLOR_TOGGLE_ICON_CLASS);
toggleIcon.src = getModeIconSrc(isDarkMode);
toggleIcon.alt = "Color mode toggle icon";
toggleIcon.setAttribute("aria-hidden", "true");
toggleIcon.setAttribute("key", "toggle icon");
const colorModeButton = document.createElement("button");
colorModeButton.classList.add("color-toggle");
colorModeButton.setAttribute("type", "button");
colorModeButton.setAttribute("aria-label", "Toggle light dark mode");
colorModeButton.setAttribute("key", "color mode button");
colorModeButton.addEventListener("click", toggleColorMode);
colorModeButton.appendChild(toggleIcon);
navButtonContainer.appendChild(colorModeButton);
// Build mobile hamburger menu
const menuIcon = document.createElement("img");
menuIcon.classList.add(COLOR_TOGGLE_ICON_CLASS);
menuIcon.src = getMenuIconSrc(isDarkMode);
menuIcon.alt = "Toggle menu";
menuIcon.setAttribute("aria-hidden", "true");
menuIcon.setAttribute("key", "menu icon");
const menuButton = document.createElement("button");
menuButton.classList.add("color-toggle");
menuButton.classList.add("mobile-menu-button");
menuButton.setAttribute("type", "button");
menuButton.setAttribute("aria-label", "Toggle menu");
menuButton.setAttribute("key", "menu button");
menuButton.addEventListener("click", toggleMenu);
menuButton.appendChild(menuIcon);
navButtonContainer.appendChild(menuButton);
}
const updateActiveNavLink = () => {
const navLinks = document.querySelectorAll(".unified-header .nav-link");
navLinks.forEach((link) => {
const href = link.getAttribute("href");
if (document.documentURI.includes("contributing.html")) {
link.classList[href.includes("contributing.html") ? "add" : "remove"](
"active"
);
} else {
link.classList[document.documentURI.includes(href) ? "add" : "remove"](
"active"
);
}
});
};
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);
});
// Rearrange DOM elements for styling
rearrangeDom();
// Check localStorage for existing color scheme preference
var prefersDark = localStorage.getItem(LS_COLOR_SCHEME) == DARK;
// Check link for search param "color"... it may be "light" or "dark"
var urlParams = new URLSearchParams(window.location.search);
if (urlParams.size > 0) {
// This is used for color mode continuity between the main Solidity Lang site and the docs
var colorSchemeParam = urlParams.get("color");
// If present, overwrite prefersDark accordingly
if (colorSchemeParam) {
prefersDark = colorSchemeParam == DARK;
}
// Remove "color" search param from URL
const { location, title } = document;
const { pathname, origin, search, hash } = location;
const newSearchParams = new URLSearchParams(search);
newSearchParams.delete("color");
const sanitizedSearch =
newSearchParams.size < 1 ? "" : "?" + newSearchParams.toString();
window.history.replaceState(
origin,
title,
pathname + sanitizedSearch + hash
);
}
// In case none existed, establish localStorage color scheme preference
var mode = prefersDark ? DARK : LIGHT;
localStorage.setItem(LS_COLOR_SCHEME, mode);
// Select the root element and set the style attribute to denote color-scheme attribute
document
.querySelector(":root")
.setAttribute("style", `--color-scheme: ${mode}`);
// Remove old input and RTD logo anchor element
document.querySelector("input[name=mode]").remove();
document.querySelector("label[for=switch]").remove();
document.querySelector(".wy-side-nav-search > a").remove();
// Add footer note
addFooterNote();
// Build header
buildHeader();
// Close menu
toggleMenu({ force: false });
// Update active nav link
updateActiveNavLink();
}
document.addEventListener("DOMContentLoaded", initialize);
const handleClick = (e) => {
if (e.target.closest(".backdrop")) {
toggleMenu({ force: false });
}
if (e.target.closest("a")) {
const target = e.target.closest("a");
const href = target.getAttribute("href");
if (href.includes(SOLIDITY_HOME_URL)) {
const url = new URL(href);
const params = new URLSearchParams(url.search);
params.set("color", localStorage.getItem(LS_COLOR_SCHEME));
url.search = params.toString();
target.setAttribute("href", url.toString());
}
}
};
document.addEventListener("click", handleClick);
const handleKeyDown = (e) => {
if (e.metaKey && e.key === "k") {
document.querySelector("#rtd-search-form input").focus();
} else if (e.key === "Escape") {
toggleMenu({ force: false });
}
if (e.metaKey && e.code === "Backslash") {
toggleColorMode();
}
};
document.addEventListener("keydown", handleKeyDown);

View File

@ -1,39 +1,47 @@
document.addEventListener('DOMContentLoaded', function() { function toggleColorMode() {
// Check localStorage for previous color scheme preference, assign the opposite
var newMode = localStorage.getItem(LS_COLOR_SCHEME) == DARK ? LIGHT : DARK;
function toggleCssMode(isDay) { // Update localStorage with new color scheme preference
var mode = (isDay ? "Day" : "Night"); localStorage.setItem(LS_COLOR_SCHEME, newMode);
localStorage.setItem("css-mode", mode);
var url_root = DOCUMENTATION_OPTIONS.URL_ROOT == "./" ? "" : DOCUMENTATION_OPTIONS.URL_ROOT; // Update the root element with the new color scheme preference
var daysheet = $(`link[href="${url_root}_static/pygments.css"]`)[0].sheet; document
daysheet.disabled = !isDay; .querySelector(":root")
.setAttribute("style", `--color-scheme: ${newMode}`);
var nightsheet = $(`link[href="${url_root}_static/css/dark.css"]`)[0]; // Update logo
if (!isDay && nightsheet === undefined) { document
var element = document.createElement("link"); .querySelector(`img.${SOLIDITY_LOGO_CLASS}`)
element.setAttribute("rel", "stylesheet"); .setAttribute("src", newMode === LIGHT ? LIGHT_LOGO_PATH : DARK_LOGO_PATH);
element.setAttribute("type", "text/css");
element.setAttribute("href", `${url_root}_static/css/dark.css`); // Update color mode toggle icon
document.getElementsByTagName("head")[0].appendChild(element); document
return; .querySelector(`img.${COLOR_TOGGLE_ICON_CLASS}`)
} .setAttribute("src", newMode === LIGHT ? MOON_ICON_PATH : SUN_ICON_PATH);
if (nightsheet !== undefined) {
nightsheet.sheet.disabled = isDay; // Update hamburger menu icon color
} document
.querySelector("button.mobile-menu-button img")
.setAttribute(
"src",
newMode === LIGHT ? LIGHT_HAMBURGER_PATH : DARK_HAMBURGER_PATH
);
}
function toggleMenu(options = {}) {
const handleClassToggle = ({ classList }, className) => {
if (typeof options.force !== "undefined") {
classList.toggle(className, options.force);
} else {
classList.toggle(className);
} }
};
var initial = localStorage.getItem("css-mode") != "Night"; document
var checkbox = document.querySelector('input[name=mode]'); .querySelectorAll('[data-toggle="rst-versions"]')
.forEach((e) => handleClassToggle(e, MOBILE_MENU_TOGGLE_CLASS));
toggleCssMode(initial); document
checkbox.checked = initial; .querySelectorAll('[data-toggle="wy-nav-shift"]')
.forEach((e) => handleClassToggle(e, MOBILE_MENU_TOGGLE_CLASS));
checkbox.addEventListener('change', function() { handleClassToggle(document.querySelector(`.${WRAPPER_CLASS}`), "menu-open");
document.documentElement.classList.add('transition'); }
window.setTimeout(() => {
document.documentElement.classList.remove('transition');
}, 1000)
toggleCssMode(this.checked);
})
});

View File

@ -31,7 +31,10 @@ def setup(sphinx):
sphinx.add_lexer('Solidity', SolidityLexer) sphinx.add_lexer('Solidity', SolidityLexer)
sphinx.add_lexer('Yul', YulLexer) sphinx.add_lexer('Yul', YulLexer)
sphinx.add_css_file('css/fonts.css')
sphinx.add_css_file('css/custom.css') sphinx.add_css_file('css/custom.css')
sphinx.add_css_file('css/custom-dark.css')
sphinx.add_css_file('css/pygments.css')
# -- General configuration ------------------------------------------------ # -- General configuration ------------------------------------------------
@ -132,7 +135,6 @@ html_theme = 'sphinx_rtd_theme'
# documentation. # documentation.
html_theme_options = { html_theme_options = {
'logo_only': True, 'logo_only': True,
'style_nav_header_background': '#65afff',
'display_version': True, 'display_version': True,
} }
@ -148,12 +150,12 @@ html_theme_options = {
# The name of an image file (relative to this directory) to place at the top # The name of an image file (relative to this directory) to place at the top
# of the sidebar. # of the sidebar.
html_logo = "logo.svg" # html_logo = "logo.svg"
# The name of an image file (within the static path) to use as favicon of the # The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large. # pixels large.
html_favicon = "_static/img/favicon.png" html_favicon = "_static/img/favicon.ico"
# Add any paths that contain custom static files (such as style sheets) here, # Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files, # relative to this directory. They are copied after the builtin static files,
@ -162,12 +164,12 @@ html_static_path = ['_static']
html_css_files = ["css/toggle.css"] html_css_files = ["css/toggle.css"]
html_js_files = ["js/toggle.js"] html_js_files = ["js/constants.js", "js/initialize.js", "js/toggle.js"]
# Add any extra paths that contain custom files (such as robots.txt or # Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied # .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation. # directly to the root of the documentation.
html_extra_path = ["_static/css"] html_extra_path = ["_static/css", "_static/fonts"]
# List of templates of static files to be included in the HTML output. # List of templates of static files to be included in the HTML output.
# Keys represent paths to input files and values are dicts containing: # Keys represent paths to input files and values are dicts containing:
@ -210,7 +212,7 @@ html_extra_templates = {
#html_show_sourcelink = True #html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True html_show_sphinx = False
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True #html_show_copyright = True

View File

@ -65,7 +65,7 @@ inheritance.
Types defined inside interfaces and other contract-like structures Types defined inside interfaces and other contract-like structures
can be accessed from other contracts: ``Token.TokenType`` or ``Token.Coin``. can be accessed from other contracts: ``Token.TokenType`` or ``Token.Coin``.
.. warning: .. warning::
Interfaces have supported ``enum`` types since :doc:`Solidity version 0.5.0 <050-breaking-changes>`, make Interfaces have supported ``enum`` types since :doc:`Solidity version 0.5.0 <050-breaking-changes>`, make
sure the pragma version specifies this version as a minimum. sure the pragma version specifies this version as a minimum.

View File

@ -1,27 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <svg width="100" height="160" viewBox="0 0 100 160" fill="#2B247C" xmlns="http://www.w3.org/2000/svg">
<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <path opacity="0.8" d="M50 44.3013L25 1L0 44.3013L25 87.6025L50 44.3013Z" />
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <path opacity="0.45" d="M50 44.3091L75 1.00781L25 1.00781L0 44.3091H50Z" />
<svg version="1.1" id="Layer_1" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" <path opacity="0.6" d="M75 1.00781L25 1.00781L50 44.3091H100L75 1.00781Z" />
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1300px" height="1300px" <path opacity="0.8" d="M50 115.699L75 159L100 115.699L75 72.3975L50 115.699Z" />
viewBox="0 0 1300 1300" enable-background="new 0 0 1300 1300" xml:space="preserve"> <path opacity="0.45" d="M50 115.691L25 158.993H75L100 115.691L50 115.691Z" />
<title>Vector 1</title> <path opacity="0.6" d="M25 158.993H75L50 115.691L0 115.691L25 158.993Z" />
<desc>Created with Sketch.</desc>
<g id="Page-1" sketch:type="MSPage">
<g id="solidity" transform="translate(402.000000, 118.000000)" sketch:type="MSLayerGroup">
<g id="Group" sketch:type="MSShapeGroup">
<path id="Shape" opacity="0.45" enable-background="new " d="M371.772,135.308L241.068,367.61H-20.158l130.614-232.302
H371.772"/>
<path id="Shape_1_" opacity="0.6" enable-background="new " d="M241.068,367.61h261.318L371.772,135.308H110.456
L241.068,367.61z"/>
<path id="Shape_2_" opacity="0.8" enable-background="new " d="M110.456,599.822L241.068,367.61L110.456,135.308
L-20.158,367.61L110.456,599.822z"/>
<path id="Shape_3_" opacity="0.45" enable-background="new " d="M111.721,948.275l130.704-232.303h261.318L373.038,948.275
H111.721"/>
<path id="Shape_4_" opacity="0.6" enable-background="new " d="M242.424,715.973H-18.893l130.613,232.303h261.317
L242.424,715.973z"/>
<path id="Shape_5_" opacity="0.8" enable-background="new " d="M373.038,483.761L242.424,715.973l130.614,232.303
l130.704-232.303L373.038,483.761z"/>
</g>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 574 B

View File

@ -636,7 +636,7 @@ expression type.
It is also helpful to cast the called contract's variable as the type of the It is also helpful to cast the called contract's variable as the type of the
most derived type in case of inheritance. most derived type in case of inheritance.
.. code-block:: solidity .. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0; pragma solidity >=0.8.0;
@ -697,8 +697,9 @@ storage for ``address`` variables, therefore if ``B.a`` had type ``address``
the encoding would assume that its storage does not change in between the encoding would assume that its storage does not change in between
transactions to ``B``. transactions to ``B``.
.. code-block:: solidity .. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0; pragma solidity >=0.8.0;
contract A { contract A {

View File

@ -380,7 +380,7 @@ The following properties are available for a contract type ``C``:
In addition to the properties above, the following properties are available In addition to the properties above, the following properties are available
for an interface type ``I``: for an interface type ``I``:
``type(I).interfaceId``: ``type(I).interfaceId``
A ``bytes4`` value containing the `EIP-165 <https://eips.ethereum.org/EIPS/eip-165>`_ A ``bytes4`` value containing the `EIP-165 <https://eips.ethereum.org/EIPS/eip-165>`_
interface identifier of the given interface ``I``. This identifier is defined as the ``XOR`` of all interface identifier of the given interface ``I``. This identifier is defined as the ``XOR`` of all
function selectors defined within the interface itself - excluding all inherited functions. function selectors defined within the interface itself - excluding all inherited functions.

View File

@ -316,7 +316,8 @@ Input Description
}, },
// Version of the EVM to compile for. // Version of the EVM to compile for.
// Affects type checking and code generation. Can be homestead, // Affects type checking and code generation. Can be homestead,
// tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg, istanbul, berlin, london or paris // tangerineWhistle, spuriousDragon, byzantium, constantinople,
// petersburg, istanbul, berlin, london, paris or shanghai (default)
"evmVersion": "byzantium", "evmVersion": "byzantium",
// Optional: Change compilation pipeline to go through the Yul intermediate representation. // Optional: Change compilation pipeline to go through the Yul intermediate representation.
// This is false by default. // This is false by default.

View File

@ -51,7 +51,6 @@
#include <liblangutil/CharStream.h> #include <liblangutil/CharStream.h>
#include <liblangutil/Exceptions.h> #include <liblangutil/Exceptions.h>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::langutil; using namespace solidity::langutil;
@ -79,21 +78,21 @@ char CharStream::setPosition(size_t _location)
return get(); return get();
} }
string CharStream::lineAtPosition(int _position) const std::string CharStream::lineAtPosition(int _position) const
{ {
// if _position points to \n, it returns the line before the \n // if _position points to \n, it returns the line before the \n
using size_type = string::size_type; using size_type = std::string::size_type;
size_type searchStart = min<size_type>(m_source.size(), size_type(_position)); size_type searchStart = std::min<size_type>(m_source.size(), size_type(_position));
if (searchStart > 0) if (searchStart > 0)
searchStart--; searchStart--;
size_type lineStart = m_source.rfind('\n', searchStart); size_type lineStart = m_source.rfind('\n', searchStart);
if (lineStart == string::npos) if (lineStart == std::string::npos)
lineStart = 0; lineStart = 0;
else else
lineStart++; lineStart++;
string line = m_source.substr( std::string line = m_source.substr(
lineStart, lineStart,
min(m_source.find('\n', lineStart), m_source.size()) - lineStart std::min(m_source.find('\n', lineStart), m_source.size()) - lineStart
); );
if (!line.empty() && line.back() == '\r') if (!line.empty() && line.back() == '\r')
line.pop_back(); line.pop_back();
@ -102,9 +101,9 @@ string CharStream::lineAtPosition(int _position) const
LineColumn CharStream::translatePositionToLineColumn(int _position) const LineColumn CharStream::translatePositionToLineColumn(int _position) const
{ {
using size_type = string::size_type; using size_type = std::string::size_type;
using diff_type = string::difference_type; using diff_type = std::string::difference_type;
size_type searchPosition = min<size_type>(m_source.size(), size_type(_position)); size_type searchPosition = std::min<size_type>(m_source.size(), size_type(_position));
int lineNumber = static_cast<int>(count(m_source.begin(), m_source.begin() + diff_type(searchPosition), '\n')); int lineNumber = static_cast<int>(count(m_source.begin(), m_source.begin() + diff_type(searchPosition), '\n'));
size_type lineStart; size_type lineStart;
if (searchPosition == 0) if (searchPosition == 0)
@ -112,24 +111,24 @@ LineColumn CharStream::translatePositionToLineColumn(int _position) const
else else
{ {
lineStart = m_source.rfind('\n', searchPosition - 1); lineStart = m_source.rfind('\n', searchPosition - 1);
lineStart = lineStart == string::npos ? 0 : lineStart + 1; lineStart = lineStart == std::string::npos ? 0 : lineStart + 1;
} }
return LineColumn{lineNumber, static_cast<int>(searchPosition - lineStart)}; return LineColumn{lineNumber, static_cast<int>(searchPosition - lineStart)};
} }
string_view CharStream::text(SourceLocation const& _location) const std::string_view CharStream::text(SourceLocation const& _location) const
{ {
if (!_location.hasText()) if (!_location.hasText())
return {}; return {};
solAssert(_location.sourceName && *_location.sourceName == m_name, ""); solAssert(_location.sourceName && *_location.sourceName == m_name, "");
solAssert(static_cast<size_t>(_location.end) <= m_source.size(), ""); solAssert(static_cast<size_t>(_location.end) <= m_source.size(), "");
return string_view{m_source}.substr( return std::string_view{m_source}.substr(
static_cast<size_t>(_location.start), static_cast<size_t>(_location.start),
static_cast<size_t>(_location.end - _location.start) static_cast<size_t>(_location.end - _location.start)
); );
} }
string CharStream::singleLineSnippet(string const& _sourceCode, SourceLocation const& _location) std::string CharStream::singleLineSnippet(std::string const& _sourceCode, SourceLocation const& _location)
{ {
if (!_location.hasText()) if (!_location.hasText())
return {}; return {};
@ -137,39 +136,39 @@ string CharStream::singleLineSnippet(string const& _sourceCode, SourceLocation c
if (static_cast<size_t>(_location.start) >= _sourceCode.size()) if (static_cast<size_t>(_location.start) >= _sourceCode.size())
return {}; return {};
string cut = _sourceCode.substr(static_cast<size_t>(_location.start), static_cast<size_t>(_location.end - _location.start)); std::string cut = _sourceCode.substr(static_cast<size_t>(_location.start), static_cast<size_t>(_location.end - _location.start));
auto newLinePos = cut.find_first_of("\n\r"); auto newLinePos = cut.find_first_of("\n\r");
if (newLinePos != string::npos) if (newLinePos != std::string::npos)
cut = cut.substr(0, newLinePos) + "..."; cut = cut.substr(0, newLinePos) + "...";
return cut; return cut;
} }
optional<int> CharStream::translateLineColumnToPosition(LineColumn const& _lineColumn) const std::optional<int> CharStream::translateLineColumnToPosition(LineColumn const& _lineColumn) const
{ {
return translateLineColumnToPosition(m_source, _lineColumn); return translateLineColumnToPosition(m_source, _lineColumn);
} }
optional<int> CharStream::translateLineColumnToPosition(std::string const& _text, LineColumn const& _input) std::optional<int> CharStream::translateLineColumnToPosition(std::string const& _text, LineColumn const& _input)
{ {
if (_input.line < 0) if (_input.line < 0)
return nullopt; return std::nullopt;
size_t offset = 0; size_t offset = 0;
for (int i = 0; i < _input.line; i++) for (int i = 0; i < _input.line; i++)
{ {
offset = _text.find('\n', offset); offset = _text.find('\n', offset);
if (offset == _text.npos) if (offset == _text.npos)
return nullopt; return std::nullopt;
offset++; // Skip linefeed. offset++; // Skip linefeed.
} }
size_t endOfLine = _text.find('\n', offset); size_t endOfLine = _text.find('\n', offset);
if (endOfLine == string::npos) if (endOfLine == std::string::npos)
endOfLine = _text.size(); endOfLine = _text.size();
if (offset + static_cast<size_t>(_input.column) > endOfLine) if (offset + static_cast<size_t>(_input.column) > endOfLine)
return nullopt; return std::nullopt;
return offset + static_cast<size_t>(_input.column); return offset + static_cast<size_t>(_input.column);
} }

View File

@ -30,7 +30,6 @@
#include <vector> #include <vector>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::langutil; using namespace solidity::langutil;
using namespace solidity::util; using namespace solidity::util;
@ -50,7 +49,7 @@ DebugInfoSelection const DebugInfoSelection::Only(bool DebugInfoSelection::* _me
return result; return result;
} }
optional<DebugInfoSelection> DebugInfoSelection::fromString(string_view _input) std::optional<DebugInfoSelection> DebugInfoSelection::fromString(std::string_view _input)
{ {
// TODO: Make more stuff constexpr and make it a static_assert(). // TODO: Make more stuff constexpr and make it a static_assert().
solAssert(componentMap().count("all") == 0, ""); solAssert(componentMap().count("all") == 0, "");
@ -61,11 +60,11 @@ optional<DebugInfoSelection> DebugInfoSelection::fromString(string_view _input)
if (_input == "none") if (_input == "none")
return None(); return None();
return fromComponents(_input | ranges::views::split(',') | ranges::to<vector<string>>); return fromComponents(_input | ranges::views::split(',') | ranges::to<std::vector<std::string>>);
} }
optional<DebugInfoSelection> DebugInfoSelection::fromComponents( std::optional<DebugInfoSelection> DebugInfoSelection::fromComponents(
vector<string> const& _componentNames, std::vector<std::string> const& _componentNames,
bool _acceptWildcards bool _acceptWildcards
) )
{ {
@ -75,16 +74,16 @@ optional<DebugInfoSelection> DebugInfoSelection::fromComponents(
for (auto const& component: _componentNames) for (auto const& component: _componentNames)
{ {
if (component == "*") if (component == "*")
return (_acceptWildcards ? make_optional(DebugInfoSelection::All()) : nullopt); return (_acceptWildcards ? std::make_optional(DebugInfoSelection::All()) : std::nullopt);
if (!selection.enable(component)) if (!selection.enable(component))
return nullopt; return std::nullopt;
} }
return selection; return selection;
} }
bool DebugInfoSelection::enable(string _component) bool DebugInfoSelection::enable(std::string _component)
{ {
auto memberIt = componentMap().find(boost::trim_copy(_component)); auto memberIt = componentMap().find(boost::trim_copy(_component));
if (memberIt == componentMap().end()) if (memberIt == componentMap().end())
@ -146,9 +145,9 @@ bool DebugInfoSelection::operator==(DebugInfoSelection const& _other) const noex
return true; return true;
} }
ostream& langutil::operator<<(ostream& _stream, DebugInfoSelection const& _selection) std::ostream& langutil::operator<<(std::ostream& _stream, DebugInfoSelection const& _selection)
{ {
vector<string> selectedComponentNames; std::vector<std::string> selectedComponentNames;
for (auto const& [name, member]: _selection.componentMap()) for (auto const& [name, member]: _selection.componentMap())
if (_selection.*member) if (_selection.*member)
selectedComponentNames.push_back(name); selectedComponentNames.push_back(name);

View File

@ -25,7 +25,6 @@
#include <liblangutil/SourceLocation.h> #include <liblangutil/SourceLocation.h>
#include <memory> #include <memory>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::langutil; using namespace solidity::langutil;
@ -37,7 +36,7 @@ ErrorReporter& ErrorReporter::operator=(ErrorReporter const& _errorReporter)
return *this; return *this;
} }
void ErrorReporter::warning(ErrorId _error, string const& _description) void ErrorReporter::warning(ErrorId _error, std::string const& _description)
{ {
error(_error, Error::Type::Warning, SourceLocation(), _description); error(_error, Error::Type::Warning, SourceLocation(), _description);
} }
@ -45,7 +44,7 @@ void ErrorReporter::warning(ErrorId _error, string const& _description)
void ErrorReporter::warning( void ErrorReporter::warning(
ErrorId _error, ErrorId _error,
SourceLocation const& _location, SourceLocation const& _location,
string const& _description std::string const& _description
) )
{ {
error(_error, Error::Type::Warning, _location, _description); error(_error, Error::Type::Warning, _location, _description);
@ -54,27 +53,27 @@ void ErrorReporter::warning(
void ErrorReporter::warning( void ErrorReporter::warning(
ErrorId _error, ErrorId _error,
SourceLocation const& _location, SourceLocation const& _location,
string const& _description, std::string const& _description,
SecondarySourceLocation const& _secondaryLocation SecondarySourceLocation const& _secondaryLocation
) )
{ {
error(_error, Error::Type::Warning, _location, _secondaryLocation, _description); error(_error, Error::Type::Warning, _location, _secondaryLocation, _description);
} }
void ErrorReporter::error(ErrorId _errorId, Error::Type _type, SourceLocation const& _location, string const& _description) void ErrorReporter::error(ErrorId _errorId, Error::Type _type, SourceLocation const& _location, std::string const& _description)
{ {
if (checkForExcessiveErrors(_type)) if (checkForExcessiveErrors(_type))
return; return;
m_errorList.push_back(make_shared<Error>(_errorId, _type, _description, _location)); m_errorList.push_back(std::make_shared<Error>(_errorId, _type, _description, _location));
} }
void ErrorReporter::error(ErrorId _errorId, Error::Type _type, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, string const& _description) void ErrorReporter::error(ErrorId _errorId, Error::Type _type, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description)
{ {
if (checkForExcessiveErrors(_type)) if (checkForExcessiveErrors(_type))
return; return;
m_errorList.push_back(make_shared<Error>(_errorId, _type, _description, _location, _secondaryLocation)); m_errorList.push_back(std::make_shared<Error>(_errorId, _type, _description, _location, _secondaryLocation));
} }
bool ErrorReporter::hasExcessiveErrors() const bool ErrorReporter::hasExcessiveErrors() const
@ -89,7 +88,7 @@ bool ErrorReporter::checkForExcessiveErrors(Error::Type _type)
m_warningCount++; m_warningCount++;
if (m_warningCount == c_maxWarningsAllowed) if (m_warningCount == c_maxWarningsAllowed)
m_errorList.push_back(make_shared<Error>(4591_error, Error::Type::Warning, "There are more than 256 warnings. Ignoring the rest.")); m_errorList.push_back(std::make_shared<Error>(4591_error, Error::Type::Warning, "There are more than 256 warnings. Ignoring the rest."));
if (m_warningCount >= c_maxWarningsAllowed) if (m_warningCount >= c_maxWarningsAllowed)
return true; return true;
@ -99,7 +98,7 @@ bool ErrorReporter::checkForExcessiveErrors(Error::Type _type)
m_infoCount++; m_infoCount++;
if (m_infoCount == c_maxInfosAllowed) if (m_infoCount == c_maxInfosAllowed)
m_errorList.push_back(make_shared<Error>(2833_error, Error::Type::Info, "There are more than 256 infos. Ignoring the rest.")); m_errorList.push_back(std::make_shared<Error>(2833_error, Error::Type::Info, "There are more than 256 infos. Ignoring the rest."));
if (m_infoCount >= c_maxInfosAllowed) if (m_infoCount >= c_maxInfosAllowed)
return true; return true;
@ -110,7 +109,7 @@ bool ErrorReporter::checkForExcessiveErrors(Error::Type _type)
if (m_errorCount > c_maxErrorsAllowed) if (m_errorCount > c_maxErrorsAllowed)
{ {
m_errorList.push_back(make_shared<Error>(4013_error, Error::Type::Warning, "There are more than 256 errors. Aborting.")); m_errorList.push_back(std::make_shared<Error>(4013_error, Error::Type::Warning, "There are more than 256 errors. Aborting."));
BOOST_THROW_EXCEPTION(FatalError()); BOOST_THROW_EXCEPTION(FatalError());
} }
} }
@ -118,13 +117,13 @@ bool ErrorReporter::checkForExcessiveErrors(Error::Type _type)
return false; return false;
} }
void ErrorReporter::fatalError(ErrorId _error, Error::Type _type, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, string const& _description) void ErrorReporter::fatalError(ErrorId _error, Error::Type _type, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description)
{ {
error(_error, _type, _location, _secondaryLocation, _description); error(_error, _type, _location, _secondaryLocation, _description);
BOOST_THROW_EXCEPTION(FatalError()); BOOST_THROW_EXCEPTION(FatalError());
} }
void ErrorReporter::fatalError(ErrorId _error, Error::Type _type, SourceLocation const& _location, string const& _description) void ErrorReporter::fatalError(ErrorId _error, Error::Type _type, SourceLocation const& _location, std::string const& _description)
{ {
error(_error, _type, _location, _description); error(_error, _type, _location, _description);
BOOST_THROW_EXCEPTION(FatalError()); BOOST_THROW_EXCEPTION(FatalError());
@ -140,7 +139,7 @@ void ErrorReporter::clear()
m_errorList.clear(); m_errorList.clear();
} }
void ErrorReporter::declarationError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, string const& _description) void ErrorReporter::declarationError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description)
{ {
error( error(
_error, _error,
@ -151,7 +150,7 @@ void ErrorReporter::declarationError(ErrorId _error, SourceLocation const& _loca
); );
} }
void ErrorReporter::declarationError(ErrorId _error, SourceLocation const& _location, string const& _description) void ErrorReporter::declarationError(ErrorId _error, SourceLocation const& _location, std::string const& _description)
{ {
error( error(
_error, _error,
@ -170,7 +169,7 @@ void ErrorReporter::fatalDeclarationError(ErrorId _error, SourceLocation const&
_description); _description);
} }
void ErrorReporter::parserError(ErrorId _error, SourceLocation const& _location, string const& _description) void ErrorReporter::parserError(ErrorId _error, SourceLocation const& _location, std::string const& _description)
{ {
error( error(
_error, _error,
@ -180,7 +179,7 @@ void ErrorReporter::parserError(ErrorId _error, SourceLocation const& _location,
); );
} }
void ErrorReporter::fatalParserError(ErrorId _error, SourceLocation const& _location, string const& _description) void ErrorReporter::fatalParserError(ErrorId _error, SourceLocation const& _location, std::string const& _description)
{ {
fatalError( fatalError(
_error, _error,
@ -190,7 +189,7 @@ void ErrorReporter::fatalParserError(ErrorId _error, SourceLocation const& _loca
); );
} }
void ErrorReporter::syntaxError(ErrorId _error, SourceLocation const& _location, string const& _description) void ErrorReporter::syntaxError(ErrorId _error, SourceLocation const& _location, std::string const& _description)
{ {
error( error(
_error, _error,
@ -200,7 +199,7 @@ void ErrorReporter::syntaxError(ErrorId _error, SourceLocation const& _location,
); );
} }
void ErrorReporter::typeError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, string const& _description) void ErrorReporter::typeError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description)
{ {
error( error(
_error, _error,
@ -211,7 +210,7 @@ void ErrorReporter::typeError(ErrorId _error, SourceLocation const& _location, S
); );
} }
void ErrorReporter::typeError(ErrorId _error, SourceLocation const& _location, string const& _description) void ErrorReporter::typeError(ErrorId _error, SourceLocation const& _location, std::string const& _description)
{ {
error( error(
_error, _error,
@ -222,7 +221,7 @@ void ErrorReporter::typeError(ErrorId _error, SourceLocation const& _location, s
} }
void ErrorReporter::fatalTypeError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, string const& _description) void ErrorReporter::fatalTypeError(ErrorId _error, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, std::string const& _description)
{ {
fatalError( fatalError(
_error, _error,
@ -233,7 +232,7 @@ void ErrorReporter::fatalTypeError(ErrorId _error, SourceLocation const& _locati
); );
} }
void ErrorReporter::fatalTypeError(ErrorId _error, SourceLocation const& _location, string const& _description) void ErrorReporter::fatalTypeError(ErrorId _error, SourceLocation const& _location, std::string const& _description)
{ {
fatalError( fatalError(
_error, _error,
@ -243,7 +242,7 @@ void ErrorReporter::fatalTypeError(ErrorId _error, SourceLocation const& _locati
); );
} }
void ErrorReporter::docstringParsingError(ErrorId _error, SourceLocation const& _location, string const& _description) void ErrorReporter::docstringParsingError(ErrorId _error, SourceLocation const& _location, std::string const& _description)
{ {
error( error(
_error, _error,
@ -256,13 +255,13 @@ void ErrorReporter::docstringParsingError(ErrorId _error, SourceLocation const&
void ErrorReporter::info( void ErrorReporter::info(
ErrorId _error, ErrorId _error,
SourceLocation const& _location, SourceLocation const& _location,
string const& _description std::string const& _description
) )
{ {
error(_error, Error::Type::Info, _location, _description); error(_error, Error::Type::Info, _location, _description);
} }
void ErrorReporter::info(ErrorId _error, string const& _description) void ErrorReporter::info(ErrorId _error, std::string const& _description)
{ {
error(_error, Error::Type::Info, SourceLocation(), _description); error(_error, Error::Type::Info, SourceLocation(), _description);
} }

View File

@ -26,7 +26,6 @@
#include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/trim.hpp> #include <boost/algorithm/string/trim.hpp>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::langutil; using namespace solidity::langutil;

View File

@ -25,7 +25,6 @@
#include <liblangutil/Scanner.h> #include <liblangutil/Scanner.h>
#include <liblangutil/ErrorReporter.h> #include <liblangutil/ErrorReporter.h>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::langutil; using namespace solidity::langutil;
@ -44,7 +43,7 @@ Token ParserBase::peekNextToken() const
return m_scanner->peekNextToken(); return m_scanner->peekNextToken();
} }
string ParserBase::currentLiteral() const std::string ParserBase::currentLiteral() const
{ {
return m_scanner->currentLiteral(); return m_scanner->currentLiteral();
} }
@ -54,7 +53,7 @@ Token ParserBase::advance()
return m_scanner->next(); return m_scanner->next();
} }
string ParserBase::tokenName(Token _token) std::string ParserBase::tokenName(Token _token)
{ {
if (_token == Token::Identifier) if (_token == Token::Identifier)
return "identifier"; return "identifier";
@ -76,7 +75,7 @@ void ParserBase::expectToken(Token _value, bool _advance)
Token tok = m_scanner->currentToken(); Token tok = m_scanner->currentToken();
if (tok != _value) if (tok != _value)
{ {
string const expectedToken = ParserBase::tokenName(_value); std::string const expectedToken = ParserBase::tokenName(_value);
if (m_parserErrorRecovery) if (m_parserErrorRecovery)
parserError(6635_error, "Expected " + expectedToken + " but got " + tokenName(tok)); parserError(6635_error, "Expected " + expectedToken + " but got " + tokenName(tok));
else else
@ -92,7 +91,7 @@ void ParserBase::expectToken(Token _value, bool _advance)
advance(); advance();
} }
void ParserBase::expectTokenOrConsumeUntil(Token _value, string const& _currentNodeName, bool _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."); solAssert(m_inParserRecovery, "The function is supposed to be called during parser recovery only.");
@ -104,12 +103,12 @@ void ParserBase::expectTokenOrConsumeUntil(Token _value, string const& _currentN
while (m_scanner->currentToken() != _value && m_scanner->currentToken() != Token::EOS) while (m_scanner->currentToken() != _value && m_scanner->currentToken() != Token::EOS)
advance(); advance();
string const expectedToken = ParserBase::tokenName(_value); std::string const expectedToken = ParserBase::tokenName(_value);
if (m_scanner->currentToken() == Token::EOS) if (m_scanner->currentToken() == Token::EOS)
{ {
// rollback to where the token started, and raise exception to be caught at a higher level. // rollback to where the token started, and raise exception to be caught at a higher level.
m_scanner->setPosition(static_cast<size_t>(startPosition)); m_scanner->setPosition(static_cast<size_t>(startPosition));
string const msg = "In " + _currentNodeName + ", " + expectedToken + "is expected; got " + ParserBase::tokenName(tok) + " instead."; std::string const msg = "In " + _currentNodeName + ", " + expectedToken + "is expected; got " + ParserBase::tokenName(tok) + " instead.";
fatalParserError(1957_error, errorLoc, msg); fatalParserError(1957_error, errorLoc, msg);
} }
else else
@ -120,7 +119,7 @@ void ParserBase::expectTokenOrConsumeUntil(Token _value, string const& _currentN
} }
else else
{ {
string expectedToken = ParserBase::tokenName(_value); std::string expectedToken = ParserBase::tokenName(_value);
parserWarning(3347_error, "Recovered in " + _currentNodeName + " at " + expectedToken + "."); parserWarning(3347_error, "Recovered in " + _currentNodeName + " at " + expectedToken + ".");
m_inParserRecovery = false; m_inParserRecovery = false;
} }
@ -142,32 +141,32 @@ void ParserBase::decreaseRecursionDepth()
m_recursionDepth--; m_recursionDepth--;
} }
void ParserBase::parserWarning(ErrorId _error, string const& _description) void ParserBase::parserWarning(ErrorId _error, std::string const& _description)
{ {
m_errorReporter.warning(_error, currentLocation(), _description); m_errorReporter.warning(_error, currentLocation(), _description);
} }
void ParserBase::parserWarning(ErrorId _error, SourceLocation const& _location, string const& _description) void ParserBase::parserWarning(ErrorId _error, SourceLocation const& _location, std::string const& _description)
{ {
m_errorReporter.warning(_error, _location, _description); m_errorReporter.warning(_error, _location, _description);
} }
void ParserBase::parserError(ErrorId _error, SourceLocation const& _location, string const& _description) void ParserBase::parserError(ErrorId _error, SourceLocation const& _location, std::string const& _description)
{ {
m_errorReporter.parserError(_error, _location, _description); m_errorReporter.parserError(_error, _location, _description);
} }
void ParserBase::parserError(ErrorId _error, string const& _description) void ParserBase::parserError(ErrorId _error, std::string const& _description)
{ {
parserError(_error, currentLocation(), _description); parserError(_error, currentLocation(), _description);
} }
void ParserBase::fatalParserError(ErrorId _error, string const& _description) void ParserBase::fatalParserError(ErrorId _error, std::string const& _description)
{ {
fatalParserError(_error, currentLocation(), _description); fatalParserError(_error, currentLocation(), _description);
} }
void ParserBase::fatalParserError(ErrorId _error, SourceLocation const& _location, string const& _description) void ParserBase::fatalParserError(ErrorId _error, SourceLocation const& _location, std::string const& _description)
{ {
m_errorReporter.fatalParserError(_error, _location, _description); m_errorReporter.fatalParserError(_error, _location, _description);
} }

View File

@ -61,12 +61,11 @@
#include <tuple> #include <tuple>
#include <array> #include <array>
using namespace std;
namespace solidity::langutil namespace solidity::langutil
{ {
string to_string(ScannerError _errorCode) std::string to_string(ScannerError _errorCode)
{ {
switch (_errorCode) switch (_errorCode)
{ {
@ -92,7 +91,7 @@ string to_string(ScannerError _errorCode)
} }
ostream& operator<<(ostream& os, ScannerError _errorCode) std::ostream& operator<<(std::ostream& os, ScannerError _errorCode)
{ {
return os << to_string(_errorCode); return os << to_string(_errorCode);
} }
@ -275,12 +274,12 @@ namespace
/// to the user. /// to the user.
static ScannerError validateBiDiMarkup(CharStream& _stream, size_t _startPosition) static ScannerError validateBiDiMarkup(CharStream& _stream, size_t _startPosition)
{ {
static array<pair<string_view, int>, 5> constexpr directionalSequences{ static std::array<std::pair<std::string_view, int>, 5> constexpr directionalSequences{
pair<string_view, int>{"\xE2\x80\xAD", 1}, // U+202D (LRO - Left-to-Right Override) std::pair<std::string_view, int>{"\xE2\x80\xAD", 1}, // U+202D (LRO - Left-to-Right Override)
pair<string_view, int>{"\xE2\x80\xAE", 1}, // U+202E (RLO - Right-to-Left Override) std::pair<std::string_view, int>{"\xE2\x80\xAE", 1}, // U+202E (RLO - Right-to-Left Override)
pair<string_view, int>{"\xE2\x80\xAA", 1}, // U+202A (LRE - Left-to-Right Embedding) std::pair<std::string_view, int>{"\xE2\x80\xAA", 1}, // U+202A (LRE - Left-to-Right Embedding)
pair<string_view, int>{"\xE2\x80\xAB", 1}, // U+202B (RLE - Right-to-Left Embedding) std::pair<std::string_view, int>{"\xE2\x80\xAB", 1}, // U+202B (RLE - Right-to-Left Embedding)
pair<string_view, int>{"\xE2\x80\xAC", -1} // U+202C (PDF - Pop Directional Formatting std::pair<std::string_view, int>{"\xE2\x80\xAC", -1} // U+202C (PDF - Pop Directional Formatting
}; };
size_t endPosition = _stream.position(); size_t endPosition = _stream.position();
@ -712,7 +711,7 @@ void Scanner::scanToken()
default: default:
if (isIdentifierStart(m_char)) if (isIdentifierStart(m_char))
{ {
tie(token, m, n) = scanIdentifierOrKeyword(); std::tie(token, m, n) = scanIdentifierOrKeyword();
// Special case for hexadecimal literals // Special case for hexadecimal literals
if (token == Token::Hex) if (token == Token::Hex)
@ -757,7 +756,7 @@ void Scanner::scanToken()
m_tokens[NextNext].location.end = static_cast<int>(sourcePos()); m_tokens[NextNext].location.end = static_cast<int>(sourcePos());
m_tokens[NextNext].location.sourceName = m_sourceName; m_tokens[NextNext].location.sourceName = m_sourceName;
m_tokens[NextNext].token = token; m_tokens[NextNext].token = token;
m_tokens[NextNext].extendedTokenInfo = make_tuple(m, n); m_tokens[NextNext].extendedTokenInfo = std::make_tuple(m, n);
} }
bool Scanner::scanEscape() bool Scanner::scanEscape()
@ -1011,7 +1010,7 @@ Token Scanner::scanNumber(char _charSeen)
return Token::Number; return Token::Number;
} }
tuple<Token, unsigned, unsigned> Scanner::scanIdentifierOrKeyword() std::tuple<Token, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
{ {
solAssert(isIdentifierStart(m_char), ""); solAssert(isIdentifierStart(m_char), "");
LiteralScope literal(this, LITERAL_TYPE_STRING); LiteralScope literal(this, LITERAL_TYPE_STRING);

View File

@ -29,18 +29,18 @@
#include <limits> #include <limits>
#include <fmt/format.h> #include <fmt/format.h>
using namespace std; using namespace std::string_literals;
using namespace solidity; using namespace solidity;
using namespace solidity::langutil; using namespace solidity::langutil;
using namespace solidity::util; using namespace solidity::util;
SemVerMatchExpressionParser::SemVerMatchExpressionParser(vector<Token> _tokens, vector<string> _literals): SemVerMatchExpressionParser::SemVerMatchExpressionParser(std::vector<Token> _tokens, std::vector<std::string> _literals):
m_tokens(std::move(_tokens)), m_literals(std::move(_literals)) m_tokens(std::move(_tokens)), m_literals(std::move(_literals))
{ {
solAssert(m_tokens.size() == m_literals.size(), ""); solAssert(m_tokens.size() == m_literals.size(), "");
} }
SemVerVersion::SemVerVersion(string const& _versionString) SemVerVersion::SemVerVersion(std::string const& _versionString)
{ {
auto i = _versionString.begin(); auto i = _versionString.begin();
auto end = _versionString.end(); auto end = _versionString.end();
@ -63,13 +63,13 @@ SemVerVersion::SemVerVersion(string const& _versionString)
{ {
auto prereleaseStart = ++i; auto prereleaseStart = ++i;
while (i != end && *i != '+') ++i; while (i != end && *i != '+') ++i;
prerelease = string(prereleaseStart, i); prerelease = std::string(prereleaseStart, i);
} }
if (i != end && *i == '+') if (i != end && *i == '+')
{ {
auto buildStart = ++i; auto buildStart = ++i;
while (i != end) ++i; while (i != end) ++i;
build = string(buildStart, i); build = std::string(buildStart, i);
} }
if (i != end) if (i != end)
solThrow(SemVerError, "Invalid versionString "s + _versionString); solThrow(SemVerError, "Invalid versionString "s + _versionString);

View File

@ -25,14 +25,13 @@
using namespace solidity; using namespace solidity;
using namespace solidity::langutil; using namespace solidity::langutil;
using namespace std;
SourceLocation solidity::langutil::parseSourceLocation(string const& _input, vector<shared_ptr<string const>> const& _sourceNames) SourceLocation solidity::langutil::parseSourceLocation(std::string const& _input, std::vector<std::shared_ptr<std::string const>> const& _sourceNames)
{ {
// Expected input: "start:length:sourceindex" // Expected input: "start:length:sourceindex"
enum SrcElem: size_t { Start, Length, Index }; enum SrcElem: size_t { Start, Length, Index };
vector<string> pos; std::vector<std::string> pos;
boost::algorithm::split(pos, _input, boost::is_any_of(":")); boost::algorithm::split(pos, _input, boost::is_any_of(":"));

View File

@ -24,7 +24,6 @@
#include <cmath> #include <cmath>
#include <variant> #include <variant>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::langutil; using namespace solidity::langutil;
@ -36,7 +35,7 @@ SourceReferenceExtractor::Message SourceReferenceExtractor::extract(
{ {
SourceLocation const* location = boost::get_error_info<errinfo_sourceLocation>(_exception); SourceLocation const* location = boost::get_error_info<errinfo_sourceLocation>(_exception);
string const* message = boost::get_error_info<util::errinfo_comment>(_exception); std::string const* message = boost::get_error_info<util::errinfo_comment>(_exception);
SourceReference primary = extract(_charStreamProvider, location, message ? *message : ""); SourceReference primary = extract(_charStreamProvider, location, message ? *message : "");
std::vector<SourceReference> secondary; std::vector<SourceReference> secondary;
@ -45,7 +44,7 @@ SourceReferenceExtractor::Message SourceReferenceExtractor::extract(
for (auto const& info: secondaryLocation->infos) for (auto const& info: secondaryLocation->infos)
secondary.emplace_back(extract(_charStreamProvider, &info.second, info.first)); secondary.emplace_back(extract(_charStreamProvider, &info.second, info.first));
return Message{std::move(primary), _typeOrSeverity, std::move(secondary), nullopt}; return Message{std::move(primary), _typeOrSeverity, std::move(secondary), std::nullopt};
} }
SourceReferenceExtractor::Message SourceReferenceExtractor::extract( SourceReferenceExtractor::Message SourceReferenceExtractor::extract(
@ -78,7 +77,7 @@ SourceReference SourceReferenceExtractor::extract(
LineColumn end = charStream.translatePositionToLineColumn(_location->end); LineColumn end = charStream.translatePositionToLineColumn(_location->end);
bool const isMultiline = start.line != end.line; bool const isMultiline = start.line != end.line;
string line = charStream.lineAtPosition(_location->start); std::string line = charStream.lineAtPosition(_location->start);
int locationLength = int locationLength =
isMultiline ? isMultiline ?
@ -88,7 +87,7 @@ SourceReference SourceReferenceExtractor::extract(
if (locationLength > 150) if (locationLength > 150)
{ {
auto const lhs = static_cast<size_t>(start.column) + 35; auto const lhs = static_cast<size_t>(start.column) + 35;
string::size_type const rhs = (isMultiline ? line.length() : static_cast<size_t>(end.column)) - 35; std::string::size_type const rhs = (isMultiline ? line.length() : static_cast<size_t>(end.column)) - 35;
line = line.substr(0, lhs) + " ... " + line.substr(rhs); line = line.substr(0, lhs) + " ... " + line.substr(rhs);
end.column = start.column + 75; end.column = start.column + 75;
locationLength = 75; locationLength = 75;
@ -98,9 +97,9 @@ SourceReference SourceReferenceExtractor::extract(
{ {
int const len = static_cast<int>(line.length()); int const len = static_cast<int>(line.length());
line = line.substr( line = line.substr(
static_cast<size_t>(max(0, start.column - 35)), static_cast<size_t>(std::max(0, start.column - 35)),
static_cast<size_t>(min(start.column, 35)) + static_cast<size_t>( static_cast<size_t>(std::min(start.column, 35)) + static_cast<size_t>(
min(locationLength + 35, len - start.column) std::min(locationLength + 35, len - start.column)
) )
); );
if (start.column + locationLength + 35 < len) if (start.column + locationLength + 35 < len)
@ -119,7 +118,7 @@ SourceReference SourceReferenceExtractor::extract(
interest, interest,
isMultiline, isMultiline,
line, line,
min(start.column, static_cast<int>(line.length())), std::min(start.column, static_cast<int>(line.length())),
min(end.column, static_cast<int>(line.length())) std::min(end.column, static_cast<int>(line.length()))
}; };
} }

View File

@ -28,7 +28,6 @@
#include <string_view> #include <string_view>
#include <variant> #include <variant>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::langutil; using namespace solidity::langutil;
using namespace solidity::util; using namespace solidity::util;
@ -114,15 +113,15 @@ void SourceReferenceFormatter::printSourceLocation(SourceReference const& _ref)
return; // No line available, nothing else to print return; // No line available, nothing else to print
} }
string line = std::to_string(_ref.position.line + 1); // one-based line number as string std::string line = std::to_string(_ref.position.line + 1); // one-based line number as string
string leftpad = string(line.size(), ' '); std::string leftpad = std::string(line.size(), ' ');
// line 0: source name // line 0: source name
m_stream << leftpad; m_stream << leftpad;
frameColored() << "-->"; frameColored() << "-->";
m_stream << ' ' << _ref.sourceName << ':' << line << ':' << (_ref.position.column + 1) << ":\n"; m_stream << ' ' << _ref.sourceName << ':' << line << ':' << (_ref.position.column + 1) << ":\n";
string_view text = _ref.text; std::string_view text = _ref.text;
if (m_charStreamProvider.charStream(_ref.sourceName).isImportedFromAST()) if (m_charStreamProvider.charStream(_ref.sourceName).isImportedFromAST())
return; return;

View File

@ -46,8 +46,6 @@
#include <map> #include <map>
using namespace std;
namespace solidity::langutil namespace solidity::langutil
{ {
@ -71,25 +69,25 @@ std::string ElementaryTypeNameToken::toString(bool const& tokenValue) const
void ElementaryTypeNameToken::assertDetails(Token _baseType, unsigned const& _first, unsigned const& _second) void ElementaryTypeNameToken::assertDetails(Token _baseType, unsigned const& _first, unsigned const& _second)
{ {
solAssert(TokenTraits::isElementaryTypeName(_baseType), "Expected elementary type name: " + string(TokenTraits::toString(_baseType))); solAssert(TokenTraits::isElementaryTypeName(_baseType), "Expected elementary type name: " + std::string(TokenTraits::toString(_baseType)));
if (_baseType == Token::BytesM) if (_baseType == Token::BytesM)
{ {
solAssert(_second == 0, "There should not be a second size argument to type bytesM."); solAssert(_second == 0, "There should not be a second size argument to type bytesM.");
solAssert(_first <= 32, "No elementary type bytes" + to_string(_first) + "."); solAssert(_first <= 32, "No elementary type bytes" + std::to_string(_first) + ".");
} }
else if (_baseType == Token::UIntM || _baseType == Token::IntM) else if (_baseType == Token::UIntM || _baseType == Token::IntM)
{ {
solAssert(_second == 0, "There should not be a second size argument to type " + string(TokenTraits::toString(_baseType)) + "."); solAssert(_second == 0, "There should not be a second size argument to type " + std::string(TokenTraits::toString(_baseType)) + ".");
solAssert( solAssert(
_first <= 256 && _first % 8 == 0, _first <= 256 && _first % 8 == 0,
"No elementary type " + string(TokenTraits::toString(_baseType)) + to_string(_first) + "." "No elementary type " + std::string(TokenTraits::toString(_baseType)) + std::to_string(_first) + "."
); );
} }
else if (_baseType == Token::UFixedMxN || _baseType == Token::FixedMxN) else if (_baseType == Token::UFixedMxN || _baseType == Token::FixedMxN)
{ {
solAssert( solAssert(
_first >= 8 && _first <= 256 && _first % 8 == 0 && _second <= 80, _first >= 8 && _first <= 256 && _first % 8 == 0 && _second <= 80,
"No elementary type " + string(TokenTraits::toString(_baseType)) + to_string(_first) + "x" + to_string(_second) + "." "No elementary type " + std::string(TokenTraits::toString(_baseType)) + std::to_string(_first) + "x" + std::to_string(_second) + "."
); );
} }
else else
@ -136,29 +134,29 @@ std::string friendlyName(Token tok)
} }
static Token keywordByName(string const& _name) static Token keywordByName(std::string const& _name)
{ {
// The following macros are used inside TOKEN_LIST and cause non-keyword tokens to be ignored // The following macros are used inside TOKEN_LIST and cause non-keyword tokens to be ignored
// and keywords to be put inside the keywords variable. // and keywords to be put inside the keywords variable.
#define KEYWORD(name, string, precedence) {string, Token::name}, #define KEYWORD(name, string, precedence) {string, Token::name},
#define TOKEN(name, string, precedence) #define TOKEN(name, string, precedence)
static map<string, Token> const keywords({TOKEN_LIST(TOKEN, KEYWORD)}); static std::map<std::string, Token> const keywords({TOKEN_LIST(TOKEN, KEYWORD)});
#undef KEYWORD #undef KEYWORD
#undef TOKEN #undef TOKEN
auto it = keywords.find(_name); auto it = keywords.find(_name);
return it == keywords.end() ? Token::Identifier : it->second; return it == keywords.end() ? Token::Identifier : it->second;
} }
bool isYulKeyword(string const& _literal) bool isYulKeyword(std::string const& _literal)
{ {
return _literal == "leave" || isYulKeyword(keywordByName(_literal)); return _literal == "leave" || isYulKeyword(keywordByName(_literal));
} }
tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(string const& _literal) std::tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(std::string const& _literal)
{ {
// Used for `bytesM`, `uintM`, `intM`, `fixedMxN`, `ufixedMxN`. // Used for `bytesM`, `uintM`, `intM`, `fixedMxN`, `ufixedMxN`.
// M/N must be shortest representation. M can never be 0. N can be zero. // M/N must be shortest representation. M can never be 0. N can be zero.
auto parseSize = [](string::const_iterator _begin, string::const_iterator _end) -> int auto parseSize = [](std::string::const_iterator _begin, std::string::const_iterator _end) -> int
{ {
// No number. // No number.
if (distance(_begin, _end) == 0) if (distance(_begin, _end) == 0)
@ -185,23 +183,23 @@ tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(string const& _
auto positionM = find_if(_literal.begin(), _literal.end(), util::isDigit); auto positionM = find_if(_literal.begin(), _literal.end(), util::isDigit);
if (positionM != _literal.end()) if (positionM != _literal.end())
{ {
string baseType(_literal.begin(), positionM); std::string baseType(_literal.begin(), positionM);
auto positionX = find_if_not(positionM, _literal.end(), util::isDigit); auto positionX = find_if_not(positionM, _literal.end(), util::isDigit);
int m = parseSize(positionM, positionX); int m = parseSize(positionM, positionX);
Token keyword = keywordByName(baseType); Token keyword = keywordByName(baseType);
if (keyword == Token::Bytes) if (keyword == Token::Bytes)
{ {
if (0 < m && m <= 32 && positionX == _literal.end()) if (0 < m && m <= 32 && positionX == _literal.end())
return make_tuple(Token::BytesM, m, 0); return std::make_tuple(Token::BytesM, m, 0);
} }
else if (keyword == Token::UInt || keyword == Token::Int) else if (keyword == Token::UInt || keyword == Token::Int)
{ {
if (0 < m && m <= 256 && m % 8 == 0 && positionX == _literal.end()) if (0 < m && m <= 256 && m % 8 == 0 && positionX == _literal.end())
{ {
if (keyword == Token::UInt) if (keyword == Token::UInt)
return make_tuple(Token::UIntM, m, 0); return std::make_tuple(Token::UIntM, m, 0);
else else
return make_tuple(Token::IntM, m, 0); return std::make_tuple(Token::IntM, m, 0);
} }
} }
else if (keyword == Token::UFixed || keyword == Token::Fixed) else if (keyword == Token::UFixed || keyword == Token::Fixed)
@ -218,16 +216,16 @@ tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(string const& _
0 <= n && n <= 80 0 <= n && n <= 80
) { ) {
if (keyword == Token::UFixed) if (keyword == Token::UFixed)
return make_tuple(Token::UFixedMxN, m, n); return std::make_tuple(Token::UFixedMxN, m, n);
else else
return make_tuple(Token::FixedMxN, m, n); return std::make_tuple(Token::FixedMxN, m, n);
} }
} }
} }
return make_tuple(Token::Identifier, 0, 0); return std::make_tuple(Token::Identifier, 0, 0);
} }
return make_tuple(keywordByName(_literal), 0, 0); return std::make_tuple(keywordByName(_literal), 0, 0);
} }
} }

View File

@ -31,20 +31,19 @@
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::util; using namespace solidity::util;
using namespace solidity::frontend; using namespace solidity::frontend;
using namespace solidity::smtutil; using namespace solidity::smtutil;
CHCSmtLib2Interface::CHCSmtLib2Interface( CHCSmtLib2Interface::CHCSmtLib2Interface(
map<h256, string> const& _queryResponses, std::map<h256, std::string> const& _queryResponses,
ReadCallback::Callback _smtCallback, ReadCallback::Callback _smtCallback,
SMTSolverChoice _enabledSolvers, SMTSolverChoice _enabledSolvers,
optional<unsigned> _queryTimeout std::optional<unsigned> _queryTimeout
): ):
CHCSolverInterface(_queryTimeout), CHCSolverInterface(_queryTimeout),
m_smtlib2(make_unique<SMTLib2Interface>(_queryResponses, _smtCallback, m_queryTimeout)), m_smtlib2(std::make_unique<SMTLib2Interface>(_queryResponses, _smtCallback, m_queryTimeout)),
m_queryResponses(std::move(_queryResponses)), m_queryResponses(std::move(_queryResponses)),
m_smtCallback(_smtCallback), m_smtCallback(_smtCallback),
m_enabledSolvers(_enabledSolvers) m_enabledSolvers(_enabledSolvers)
@ -66,8 +65,8 @@ void CHCSmtLib2Interface::registerRelation(Expression const& _expr)
smtAssert(_expr.sort->kind == Kind::Function); smtAssert(_expr.sort->kind == Kind::Function);
if (!m_variables.count(_expr.name)) if (!m_variables.count(_expr.name))
{ {
auto fSort = dynamic_pointer_cast<FunctionSort>(_expr.sort); auto fSort = std::dynamic_pointer_cast<FunctionSort>(_expr.sort);
string domain = toSmtLibSort(fSort->domain); std::string domain = toSmtLibSort(fSort->domain);
// Relations are predicates which have implicit codomain Bool. // Relations are predicates which have implicit codomain Bool.
m_variables.insert(_expr.name); m_variables.insert(_expr.name);
write( write(
@ -89,10 +88,10 @@ void CHCSmtLib2Interface::addRule(Expression const& _expr, std::string const& /*
); );
} }
tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> CHCSmtLib2Interface::query(Expression const& _block) std::tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> CHCSmtLib2Interface::query(Expression const& _block)
{ {
string query = dumpQuery(_block); std::string query = dumpQuery(_block);
string response = querySolver(query); std::string response = querySolver(query);
CheckResult result; CheckResult result;
// TODO proper parsing // TODO proper parsing
@ -108,7 +107,7 @@ tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> CHCSmtLib2Interface
return {result, Expression(true), {}}; return {result, Expression(true), {}};
} }
void CHCSmtLib2Interface::declareVariable(string const& _name, SortPointer const& _sort) void CHCSmtLib2Interface::declareVariable(std::string const& _name, SortPointer const& _sort)
{ {
smtAssert(_sort); smtAssert(_sort);
if (_sort->kind == Kind::Function) if (_sort->kind == Kind::Function)
@ -120,25 +119,25 @@ void CHCSmtLib2Interface::declareVariable(string const& _name, SortPointer const
} }
} }
string CHCSmtLib2Interface::toSmtLibSort(Sort const& _sort) std::string CHCSmtLib2Interface::toSmtLibSort(Sort const& _sort)
{ {
if (!m_sortNames.count(&_sort)) if (!m_sortNames.count(&_sort))
m_sortNames[&_sort] = m_smtlib2->toSmtLibSort(_sort); m_sortNames[&_sort] = m_smtlib2->toSmtLibSort(_sort);
return m_sortNames.at(&_sort); return m_sortNames.at(&_sort);
} }
string CHCSmtLib2Interface::toSmtLibSort(vector<SortPointer> const& _sorts) std::string CHCSmtLib2Interface::toSmtLibSort(std::vector<SortPointer> const& _sorts)
{ {
string ssort("("); std::string ssort("(");
for (auto const& sort: _sorts) for (auto const& sort: _sorts)
ssort += toSmtLibSort(*sort) + " "; ssort += toSmtLibSort(*sort) + " ";
ssort += ")"; ssort += ")";
return ssort; return ssort;
} }
string CHCSmtLib2Interface::forall() std::string CHCSmtLib2Interface::forall()
{ {
string vars("("); std::string vars("(");
for (auto const& [name, sort]: m_smtlib2->variables()) for (auto const& [name, sort]: m_smtlib2->variables())
{ {
solAssert(sort, ""); solAssert(sort, "");
@ -149,17 +148,17 @@ string CHCSmtLib2Interface::forall()
return vars; return vars;
} }
void CHCSmtLib2Interface::declareFunction(string const& _name, SortPointer const& _sort) void CHCSmtLib2Interface::declareFunction(std::string const& _name, SortPointer const& _sort)
{ {
smtAssert(_sort); smtAssert(_sort);
smtAssert(_sort->kind == Kind::Function); smtAssert(_sort->kind == Kind::Function);
// TODO Use domain and codomain as key as well // TODO Use domain and codomain as key as well
if (!m_variables.count(_name)) if (!m_variables.count(_name))
{ {
auto fSort = dynamic_pointer_cast<FunctionSort>(_sort); auto fSort = std::dynamic_pointer_cast<FunctionSort>(_sort);
smtAssert(fSort->codomain); smtAssert(fSort->codomain);
string domain = toSmtLibSort(fSort->domain); std::string domain = toSmtLibSort(fSort->domain);
string codomain = toSmtLibSort(*fSort->codomain); std::string codomain = toSmtLibSort(*fSort->codomain);
m_variables.insert(_name); m_variables.insert(_name);
write( write(
"(declare-fun |" + "(declare-fun |" +
@ -173,12 +172,12 @@ void CHCSmtLib2Interface::declareFunction(string const& _name, SortPointer const
} }
} }
void CHCSmtLib2Interface::write(string _data) void CHCSmtLib2Interface::write(std::string _data)
{ {
m_accumulatedOutput += std::move(_data) + "\n"; m_accumulatedOutput += std::move(_data) + "\n";
} }
string CHCSmtLib2Interface::querySolver(string const& _input) std::string CHCSmtLib2Interface::querySolver(std::string const& _input)
{ {
util::h256 inputHash = util::keccak256(_input); util::h256 inputHash = util::keccak256(_input);
if (m_queryResponses.count(inputHash)) if (m_queryResponses.count(inputHash))
@ -212,7 +211,7 @@ std::string CHCSmtLib2Interface::dumpQuery(Expression const& _expr)
std::string CHCSmtLib2Interface::createHeaderAndDeclarations() { std::string CHCSmtLib2Interface::createHeaderAndDeclarations() {
std::stringstream s; std::stringstream s;
if (m_queryTimeout) if (m_queryTimeout)
s << "(set-option :timeout " + to_string(*m_queryTimeout) + ")\n"; s << "(set-option :timeout " + std::to_string(*m_queryTimeout) + ")\n";
s << "(set-logic HORN)" << std::endl; s << "(set-logic HORN)" << std::endl;
for (auto const& decl: m_smtlib2->userSorts() | ranges::views::values) for (auto const& decl: m_smtlib2->userSorts() | ranges::views::values)

View File

@ -23,12 +23,11 @@
#include <cvc4/util/bitvector.h> #include <cvc4/util/bitvector.h>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::util; using namespace solidity::util;
using namespace solidity::smtutil; using namespace solidity::smtutil;
CVC4Interface::CVC4Interface(optional<unsigned> _queryTimeout): CVC4Interface::CVC4Interface(std::optional<unsigned> _queryTimeout):
SolverInterface(_queryTimeout), SolverInterface(_queryTimeout),
m_solver(&m_context) m_solver(&m_context)
{ {
@ -56,7 +55,7 @@ void CVC4Interface::pop()
m_solver.pop(); m_solver.pop();
} }
void CVC4Interface::declareVariable(string const& _name, SortPointer const& _sort) void CVC4Interface::declareVariable(std::string const& _name, SortPointer const& _sort)
{ {
smtAssert(_sort, ""); smtAssert(_sort, "");
m_variables[_name] = m_context.mkVar(_name.c_str(), cvc4Sort(*_sort)); m_variables[_name] = m_context.mkVar(_name.c_str(), cvc4Sort(*_sort));
@ -86,10 +85,10 @@ void CVC4Interface::addAssertion(Expression const& _expr)
} }
} }
pair<CheckResult, vector<string>> CVC4Interface::check(vector<Expression> const& _expressionsToEvaluate) std::pair<CheckResult, std::vector<std::string>> CVC4Interface::check(std::vector<Expression> const& _expressionsToEvaluate)
{ {
CheckResult result; CheckResult result;
vector<string> values; std::vector<std::string> values;
try try
{ {
switch (m_solver.checkSat().isSat()) switch (m_solver.checkSat().isSat())
@ -119,7 +118,7 @@ pair<CheckResult, vector<string>> CVC4Interface::check(vector<Expression> const&
values.clear(); values.clear();
} }
return make_pair(result, values); return std::make_pair(result, values);
} }
CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr) CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
@ -128,13 +127,13 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
if (_expr.arguments.empty() && m_variables.count(_expr.name)) if (_expr.arguments.empty() && m_variables.count(_expr.name))
return m_variables.at(_expr.name); return m_variables.at(_expr.name);
vector<CVC4::Expr> arguments; std::vector<CVC4::Expr> arguments;
for (auto const& arg: _expr.arguments) for (auto const& arg: _expr.arguments)
arguments.push_back(toCVC4Expr(arg)); arguments.push_back(toCVC4Expr(arg));
try try
{ {
string const& n = _expr.name; std::string const& n = _expr.name;
// Function application // Function application
if (!arguments.empty() && m_variables.count(_expr.name)) if (!arguments.empty() && m_variables.count(_expr.name))
return m_context.mkExpr(CVC4::kind::APPLY_UF, m_variables.at(n), arguments); return m_context.mkExpr(CVC4::kind::APPLY_UF, m_variables.at(n), arguments);
@ -145,7 +144,7 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
return m_context.mkConst(true); return m_context.mkConst(true);
else if (n == "false") else if (n == "false")
return m_context.mkConst(false); return m_context.mkConst(false);
else if (auto sortSort = dynamic_pointer_cast<SortSort>(_expr.sort)) else if (auto sortSort = std::dynamic_pointer_cast<SortSort>(_expr.sort))
return m_context.mkVar(n, cvc4Sort(*sortSort->inner)); return m_context.mkVar(n, cvc4Sort(*sortSort->inner));
else else
try try
@ -224,7 +223,7 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
} }
else if (n == "bv2int") else if (n == "bv2int")
{ {
auto intSort = dynamic_pointer_cast<IntSort>(_expr.sort); auto intSort = std::dynamic_pointer_cast<IntSort>(_expr.sort);
smtAssert(intSort, ""); smtAssert(intSort, "");
auto nat = m_context.mkExpr(CVC4::kind::BITVECTOR_TO_NAT, arguments[0]); auto nat = m_context.mkExpr(CVC4::kind::BITVECTOR_TO_NAT, arguments[0]);
if (!intSort->isSigned) if (!intSort->isSigned)
@ -254,13 +253,13 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
return m_context.mkExpr(CVC4::kind::STORE, arguments[0], arguments[1], arguments[2]); return m_context.mkExpr(CVC4::kind::STORE, arguments[0], arguments[1], arguments[2]);
else if (n == "const_array") else if (n == "const_array")
{ {
shared_ptr<SortSort> sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments[0].sort); std::shared_ptr<SortSort> sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments[0].sort);
smtAssert(sortSort, ""); smtAssert(sortSort, "");
return m_context.mkConst(CVC4::ArrayStoreAll(cvc4Sort(*sortSort->inner), arguments[1])); return m_context.mkConst(CVC4::ArrayStoreAll(cvc4Sort(*sortSort->inner), arguments[1]));
} }
else if (n == "tuple_get") else if (n == "tuple_get")
{ {
shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.arguments[0].sort); std::shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.arguments[0].sort);
smtAssert(tupleSort, ""); smtAssert(tupleSort, "");
CVC4::DatatypeType tt = m_context.mkTupleType(cvc4Sort(tupleSort->components)); CVC4::DatatypeType tt = m_context.mkTupleType(cvc4Sort(tupleSort->components));
CVC4::Datatype const& dt = tt.getDatatype(); CVC4::Datatype const& dt = tt.getDatatype();
@ -270,7 +269,7 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
} }
else if (n == "tuple_constructor") else if (n == "tuple_constructor")
{ {
shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.sort); std::shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.sort);
smtAssert(tupleSort, ""); smtAssert(tupleSort, "");
CVC4::DatatypeType tt = m_context.mkTupleType(cvc4Sort(tupleSort->components)); CVC4::DatatypeType tt = m_context.mkTupleType(cvc4Sort(tupleSort->components));
CVC4::Datatype const& dt = tt.getDatatype(); CVC4::Datatype const& dt = tt.getDatatype();
@ -328,9 +327,9 @@ CVC4::Type CVC4Interface::cvc4Sort(Sort const& _sort)
return m_context.integerType(); return m_context.integerType();
} }
vector<CVC4::Type> CVC4Interface::cvc4Sort(vector<SortPointer> const& _sorts) std::vector<CVC4::Type> CVC4Interface::cvc4Sort(std::vector<SortPointer> const& _sorts)
{ {
vector<CVC4::Type> cvc4Sorts; std::vector<CVC4::Type> cvc4Sorts;
for (auto const& _sort: _sorts) for (auto const& _sort: _sorts)
cvc4Sorts.push_back(cvc4Sort(*_sort)); cvc4Sorts.push_back(cvc4Sort(*_sort));
return cvc4Sorts; return cvc4Sorts;

View File

@ -33,16 +33,15 @@
#include <string> #include <string>
#include <utility> #include <utility>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::util; using namespace solidity::util;
using namespace solidity::frontend; using namespace solidity::frontend;
using namespace solidity::smtutil; using namespace solidity::smtutil;
SMTLib2Interface::SMTLib2Interface( SMTLib2Interface::SMTLib2Interface(
map<h256, string> _queryResponses, std::map<h256, std::string> _queryResponses,
ReadCallback::Callback _smtCallback, ReadCallback::Callback _smtCallback,
optional<unsigned> _queryTimeout std::optional<unsigned> _queryTimeout
): ):
SolverInterface(_queryTimeout), SolverInterface(_queryTimeout),
m_queryResponses(std::move(_queryResponses)), m_queryResponses(std::move(_queryResponses)),
@ -59,7 +58,7 @@ void SMTLib2Interface::reset()
m_userSorts.clear(); m_userSorts.clear();
write("(set-option :produce-models true)"); write("(set-option :produce-models true)");
if (m_queryTimeout) if (m_queryTimeout)
write("(set-option :timeout " + to_string(*m_queryTimeout) + ")"); write("(set-option :timeout " + std::to_string(*m_queryTimeout) + ")");
write("(set-logic ALL)"); write("(set-logic ALL)");
} }
@ -74,7 +73,7 @@ void SMTLib2Interface::pop()
m_accumulatedOutput.pop_back(); m_accumulatedOutput.pop_back();
} }
void SMTLib2Interface::declareVariable(string const& _name, SortPointer const& _sort) void SMTLib2Interface::declareVariable(std::string const& _name, SortPointer const& _sort)
{ {
smtAssert(_sort, ""); smtAssert(_sort, "");
if (_sort->kind == Kind::Function) if (_sort->kind == Kind::Function)
@ -86,16 +85,16 @@ void SMTLib2Interface::declareVariable(string const& _name, SortPointer const& _
} }
} }
void SMTLib2Interface::declareFunction(string const& _name, SortPointer const& _sort) void SMTLib2Interface::declareFunction(std::string const& _name, SortPointer const& _sort)
{ {
smtAssert(_sort, ""); smtAssert(_sort, "");
smtAssert(_sort->kind == Kind::Function, ""); smtAssert(_sort->kind == Kind::Function, "");
// TODO Use domain and codomain as key as well // TODO Use domain and codomain as key as well
if (!m_variables.count(_name)) if (!m_variables.count(_name))
{ {
auto const& fSort = dynamic_pointer_cast<FunctionSort>(_sort); auto const& fSort = std::dynamic_pointer_cast<FunctionSort>(_sort);
string domain = toSmtLibSort(fSort->domain); std::string domain = toSmtLibSort(fSort->domain);
string codomain = toSmtLibSort(*fSort->codomain); std::string codomain = toSmtLibSort(*fSort->codomain);
m_variables.emplace(_name, _sort); m_variables.emplace(_name, _sort);
write( write(
"(declare-fun |" + "(declare-fun |" +
@ -114,9 +113,9 @@ void SMTLib2Interface::addAssertion(Expression const& _expr)
write("(assert " + toSExpr(_expr) + ")"); write("(assert " + toSExpr(_expr) + ")");
} }
pair<CheckResult, vector<string>> SMTLib2Interface::check(vector<Expression> const& _expressionsToEvaluate) std::pair<CheckResult, std::vector<std::string>> SMTLib2Interface::check(std::vector<Expression> const& _expressionsToEvaluate)
{ {
string response = querySolver( std::string response = querySolver(
boost::algorithm::join(m_accumulatedOutput, "\n") + boost::algorithm::join(m_accumulatedOutput, "\n") +
checkSatAndGetValuesCommand(_expressionsToEvaluate) checkSatAndGetValuesCommand(_expressionsToEvaluate)
); );
@ -132,13 +131,13 @@ pair<CheckResult, vector<string>> SMTLib2Interface::check(vector<Expression> con
else else
result = CheckResult::ERROR; result = CheckResult::ERROR;
vector<string> values; std::vector<std::string> values;
if (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty()) if (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty())
values = parseValues(find(response.cbegin(), response.cend(), '\n'), response.cend()); values = parseValues(find(response.cbegin(), response.cend(), '\n'), response.cend());
return make_pair(result, values); return std::make_pair(result, values);
} }
string SMTLib2Interface::toSExpr(Expression const& _expr) std::string SMTLib2Interface::toSExpr(Expression const& _expr)
{ {
if (_expr.arguments.empty()) if (_expr.arguments.empty())
return _expr.name; return _expr.name;
@ -148,16 +147,16 @@ string SMTLib2Interface::toSExpr(Expression const& _expr)
{ {
size_t size = std::stoul(_expr.arguments[1].name); size_t size = std::stoul(_expr.arguments[1].name);
auto arg = toSExpr(_expr.arguments.front()); auto arg = toSExpr(_expr.arguments.front());
auto int2bv = "(_ int2bv " + to_string(size) + ")"; auto int2bv = "(_ int2bv " + std::to_string(size) + ")";
// Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed. // Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed.
sexpr += string("ite ") + sexpr += std::string("ite ") +
"(>= " + arg + " 0) " + "(>= " + arg + " 0) " +
"(" + int2bv + " " + arg + ") " + "(" + int2bv + " " + arg + ") " +
"(bvneg (" + int2bv + " (- " + arg + ")))"; "(bvneg (" + int2bv + " (- " + arg + ")))";
} }
else if (_expr.name == "bv2int") else if (_expr.name == "bv2int")
{ {
auto intSort = dynamic_pointer_cast<IntSort>(_expr.sort); auto intSort = std::dynamic_pointer_cast<IntSort>(_expr.sort);
smtAssert(intSort, ""); smtAssert(intSort, "");
auto arg = toSExpr(_expr.arguments.front()); auto arg = toSExpr(_expr.arguments.front());
@ -166,13 +165,13 @@ string SMTLib2Interface::toSExpr(Expression const& _expr)
if (!intSort->isSigned) if (!intSort->isSigned)
return nat; return nat;
auto bvSort = dynamic_pointer_cast<BitVectorSort>(_expr.arguments.front().sort); auto bvSort = std::dynamic_pointer_cast<BitVectorSort>(_expr.arguments.front().sort);
smtAssert(bvSort, ""); smtAssert(bvSort, "");
auto size = to_string(bvSort->size); auto size = std::to_string(bvSort->size);
auto pos = to_string(bvSort->size - 1); auto pos = std::to_string(bvSort->size - 1);
// Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed. // Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed.
sexpr += string("ite ") + sexpr += std::string("ite ") +
"(= ((_ extract " + pos + " " + pos + ")" + arg + ") #b0) " + "(= ((_ extract " + pos + " " + pos + ")" + arg + ") #b0) " +
nat + " " + nat + " " +
"(- (bv2nat (bvneg " + arg + ")))"; "(- (bv2nat (bvneg " + arg + ")))";
@ -182,7 +181,7 @@ string SMTLib2Interface::toSExpr(Expression const& _expr)
smtAssert(_expr.arguments.size() == 2, ""); smtAssert(_expr.arguments.size() == 2, "");
auto sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments.at(0).sort); auto sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments.at(0).sort);
smtAssert(sortSort, ""); smtAssert(sortSort, "");
auto arraySort = dynamic_pointer_cast<ArraySort>(sortSort->inner); auto arraySort = std::dynamic_pointer_cast<ArraySort>(sortSort->inner);
smtAssert(arraySort, ""); smtAssert(arraySort, "");
sexpr += "(as const " + toSmtLibSort(*arraySort) + ") "; sexpr += "(as const " + toSmtLibSort(*arraySort) + ") ";
sexpr += toSExpr(_expr.arguments.at(1)); sexpr += toSExpr(_expr.arguments.at(1));
@ -190,14 +189,14 @@ string SMTLib2Interface::toSExpr(Expression const& _expr)
else if (_expr.name == "tuple_get") else if (_expr.name == "tuple_get")
{ {
smtAssert(_expr.arguments.size() == 2, ""); smtAssert(_expr.arguments.size() == 2, "");
auto tupleSort = dynamic_pointer_cast<TupleSort>(_expr.arguments.at(0).sort); auto tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.arguments.at(0).sort);
size_t index = std::stoul(_expr.arguments.at(1).name); size_t index = std::stoul(_expr.arguments.at(1).name);
smtAssert(index < tupleSort->members.size(), ""); smtAssert(index < tupleSort->members.size(), "");
sexpr += "|" + tupleSort->members.at(index) + "| " + toSExpr(_expr.arguments.at(0)); sexpr += "|" + tupleSort->members.at(index) + "| " + toSExpr(_expr.arguments.at(0));
} }
else if (_expr.name == "tuple_constructor") else if (_expr.name == "tuple_constructor")
{ {
auto tupleSort = dynamic_pointer_cast<TupleSort>(_expr.sort); auto tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.sort);
smtAssert(tupleSort, ""); smtAssert(tupleSort, "");
sexpr += "|" + tupleSort->name + "|"; sexpr += "|" + tupleSort->name + "|";
for (auto const& arg: _expr.arguments) for (auto const& arg: _expr.arguments)
@ -213,7 +212,7 @@ string SMTLib2Interface::toSExpr(Expression const& _expr)
return sexpr; return sexpr;
} }
string SMTLib2Interface::toSmtLibSort(Sort const& _sort) std::string SMTLib2Interface::toSmtLibSort(Sort const& _sort)
{ {
switch (_sort.kind) switch (_sort.kind)
{ {
@ -222,7 +221,7 @@ string SMTLib2Interface::toSmtLibSort(Sort const& _sort)
case Kind::Bool: case Kind::Bool:
return "Bool"; return "Bool";
case Kind::BitVector: case Kind::BitVector:
return "(_ BitVec " + to_string(dynamic_cast<BitVectorSort const&>(_sort).size) + ")"; return "(_ BitVec " + std::to_string(dynamic_cast<BitVectorSort const&>(_sort).size) + ")";
case Kind::Array: case Kind::Array:
{ {
auto const& arraySort = dynamic_cast<ArraySort const&>(_sort); auto const& arraySort = dynamic_cast<ArraySort const&>(_sort);
@ -232,11 +231,11 @@ string SMTLib2Interface::toSmtLibSort(Sort const& _sort)
case Kind::Tuple: case Kind::Tuple:
{ {
auto const& tupleSort = dynamic_cast<TupleSort const&>(_sort); auto const& tupleSort = dynamic_cast<TupleSort const&>(_sort);
string tupleName = "|" + tupleSort.name + "|"; std::string tupleName = "|" + tupleSort.name + "|";
auto isName = [&](auto entry) { return entry.first == tupleName; }; auto isName = [&](auto entry) { return entry.first == tupleName; };
if (ranges::find_if(m_userSorts, isName) == m_userSorts.end()) if (ranges::find_if(m_userSorts, isName) == m_userSorts.end())
{ {
string decl("(declare-datatypes ((" + tupleName + " 0)) (((" + tupleName); std::string decl("(declare-datatypes ((" + tupleName + " 0)) (((" + tupleName);
smtAssert(tupleSort.members.size() == tupleSort.components.size(), ""); smtAssert(tupleSort.members.size() == tupleSort.components.size(), "");
for (unsigned i = 0; i < tupleSort.members.size(); ++i) for (unsigned i = 0; i < tupleSort.members.size(); ++i)
decl += " (|" + tupleSort.members.at(i) + "| " + toSmtLibSort(*tupleSort.components.at(i)) + ")"; decl += " (|" + tupleSort.members.at(i) + "| " + toSmtLibSort(*tupleSort.components.at(i)) + ")";
@ -252,24 +251,24 @@ string SMTLib2Interface::toSmtLibSort(Sort const& _sort)
} }
} }
string SMTLib2Interface::toSmtLibSort(vector<SortPointer> const& _sorts) std::string SMTLib2Interface::toSmtLibSort(std::vector<SortPointer> const& _sorts)
{ {
string ssort("("); std::string ssort("(");
for (auto const& sort: _sorts) for (auto const& sort: _sorts)
ssort += toSmtLibSort(*sort) + " "; ssort += toSmtLibSort(*sort) + " ";
ssort += ")"; ssort += ")";
return ssort; return ssort;
} }
void SMTLib2Interface::write(string _data) void SMTLib2Interface::write(std::string _data)
{ {
smtAssert(!m_accumulatedOutput.empty(), ""); smtAssert(!m_accumulatedOutput.empty(), "");
m_accumulatedOutput.back() += std::move(_data) + "\n"; m_accumulatedOutput.back() += std::move(_data) + "\n";
} }
string SMTLib2Interface::checkSatAndGetValuesCommand(vector<Expression> const& _expressionsToEvaluate) std::string SMTLib2Interface::checkSatAndGetValuesCommand(std::vector<Expression> const& _expressionsToEvaluate)
{ {
string command; std::string command;
if (_expressionsToEvaluate.empty()) if (_expressionsToEvaluate.empty())
command = "(check-sat)\n"; command = "(check-sat)\n";
else else
@ -279,22 +278,22 @@ string SMTLib2Interface::checkSatAndGetValuesCommand(vector<Expression> const& _
{ {
auto const& e = _expressionsToEvaluate.at(i); auto const& e = _expressionsToEvaluate.at(i);
smtAssert(e.sort->kind == Kind::Int || e.sort->kind == Kind::Bool, "Invalid sort for expression to evaluate."); smtAssert(e.sort->kind == Kind::Int || e.sort->kind == Kind::Bool, "Invalid sort for expression to evaluate.");
command += "(declare-const |EVALEXPR_" + to_string(i) + "| " + (e.sort->kind == Kind::Int ? "Int" : "Bool") + ")\n"; command += "(declare-const |EVALEXPR_" + std::to_string(i) + "| " + (e.sort->kind == Kind::Int ? "Int" : "Bool") + ")\n";
command += "(assert (= |EVALEXPR_" + to_string(i) + "| " + toSExpr(e) + "))\n"; command += "(assert (= |EVALEXPR_" + std::to_string(i) + "| " + toSExpr(e) + "))\n";
} }
command += "(check-sat)\n"; command += "(check-sat)\n";
command += "(get-value ("; command += "(get-value (";
for (size_t i = 0; i < _expressionsToEvaluate.size(); i++) for (size_t i = 0; i < _expressionsToEvaluate.size(); i++)
command += "|EVALEXPR_" + to_string(i) + "| "; command += "|EVALEXPR_" + std::to_string(i) + "| ";
command += "))\n"; command += "))\n";
} }
return command; return command;
} }
vector<string> SMTLib2Interface::parseValues(string::const_iterator _start, string::const_iterator _end) std::vector<std::string> SMTLib2Interface::parseValues(std::string::const_iterator _start, std::string::const_iterator _end)
{ {
vector<string> values; std::vector<std::string> values;
while (_start < _end) while (_start < _end)
{ {
auto valStart = find(_start, _end, ' '); auto valStart = find(_start, _end, ' ');
@ -308,7 +307,7 @@ vector<string> SMTLib2Interface::parseValues(string::const_iterator _start, stri
return values; return values;
} }
string SMTLib2Interface::querySolver(string const& _input) std::string SMTLib2Interface::querySolver(std::string const& _input)
{ {
h256 inputHash = keccak256(_input); h256 inputHash = keccak256(_input);
if (m_queryResponses.count(inputHash)) if (m_queryResponses.count(inputHash))
@ -323,7 +322,7 @@ string SMTLib2Interface::querySolver(string const& _input)
return "unknown\n"; return "unknown\n";
} }
string SMTLib2Interface::dumpQuery(vector<Expression> const& _expressionsToEvaluate) std::string SMTLib2Interface::dumpQuery(std::vector<Expression> const& _expressionsToEvaluate)
{ {
return boost::algorithm::join(m_accumulatedOutput, "\n") + return boost::algorithm::join(m_accumulatedOutput, "\n") +
checkSatAndGetValuesCommand(_expressionsToEvaluate); checkSatAndGetValuesCommand(_expressionsToEvaluate);

View File

@ -26,31 +26,30 @@
#endif #endif
#include <libsmtutil/SMTLib2Interface.h> #include <libsmtutil/SMTLib2Interface.h>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::util; using namespace solidity::util;
using namespace solidity::frontend; using namespace solidity::frontend;
using namespace solidity::smtutil; using namespace solidity::smtutil;
SMTPortfolio::SMTPortfolio( SMTPortfolio::SMTPortfolio(
map<h256, string> _smtlib2Responses, std::map<h256, std::string> _smtlib2Responses,
frontend::ReadCallback::Callback _smtCallback, frontend::ReadCallback::Callback _smtCallback,
[[maybe_unused]] SMTSolverChoice _enabledSolvers, [[maybe_unused]] SMTSolverChoice _enabledSolvers,
optional<unsigned> _queryTimeout, std::optional<unsigned> _queryTimeout,
bool _printQuery bool _printQuery
): ):
SolverInterface(_queryTimeout) SolverInterface(_queryTimeout)
{ {
solAssert(!_printQuery || _enabledSolvers == smtutil::SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries"); solAssert(!_printQuery || _enabledSolvers == smtutil::SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries");
if (_enabledSolvers.smtlib2) if (_enabledSolvers.smtlib2)
m_solvers.emplace_back(make_unique<SMTLib2Interface>(std::move(_smtlib2Responses), std::move(_smtCallback), m_queryTimeout)); m_solvers.emplace_back(std::make_unique<SMTLib2Interface>(std::move(_smtlib2Responses), std::move(_smtCallback), m_queryTimeout));
#ifdef HAVE_Z3 #ifdef HAVE_Z3
if (_enabledSolvers.z3 && Z3Interface::available()) if (_enabledSolvers.z3 && Z3Interface::available())
m_solvers.emplace_back(make_unique<Z3Interface>(m_queryTimeout)); m_solvers.emplace_back(std::make_unique<Z3Interface>(m_queryTimeout));
#endif #endif
#ifdef HAVE_CVC4 #ifdef HAVE_CVC4
if (_enabledSolvers.cvc4) if (_enabledSolvers.cvc4)
m_solvers.emplace_back(make_unique<CVC4Interface>(m_queryTimeout)); m_solvers.emplace_back(std::make_unique<CVC4Interface>(m_queryTimeout));
#endif #endif
} }
@ -72,7 +71,7 @@ void SMTPortfolio::pop()
s->pop(); s->pop();
} }
void SMTPortfolio::declareVariable(string const& _name, SortPointer const& _sort) void SMTPortfolio::declareVariable(std::string const& _name, SortPointer const& _sort)
{ {
smtAssert(_sort, ""); smtAssert(_sort, "");
for (auto const& s: m_solvers) for (auto const& s: m_solvers)
@ -115,14 +114,14 @@ void SMTPortfolio::addAssertion(Expression const& _expr)
* *
* If all solvers return ERROR, the result is ERROR. * If all solvers return ERROR, the result is ERROR.
*/ */
pair<CheckResult, vector<string>> SMTPortfolio::check(vector<Expression> const& _expressionsToEvaluate) std::pair<CheckResult, std::vector<std::string>> SMTPortfolio::check(std::vector<Expression> const& _expressionsToEvaluate)
{ {
CheckResult lastResult = CheckResult::ERROR; CheckResult lastResult = CheckResult::ERROR;
vector<string> finalValues; std::vector<std::string> finalValues;
for (auto const& s: m_solvers) for (auto const& s: m_solvers)
{ {
CheckResult result; CheckResult result;
vector<string> values; std::vector<std::string> values;
tie(result, values) = s->check(_expressionsToEvaluate); tie(result, values) = s->check(_expressionsToEvaluate);
if (solverAnswered(result)) if (solverAnswered(result))
{ {
@ -140,10 +139,10 @@ pair<CheckResult, vector<string>> SMTPortfolio::check(vector<Expression> const&
else if (result == CheckResult::UNKNOWN && lastResult == CheckResult::ERROR) else if (result == CheckResult::UNKNOWN && lastResult == CheckResult::ERROR)
lastResult = result; lastResult = result;
} }
return make_pair(lastResult, finalValues); return std::make_pair(lastResult, finalValues);
} }
vector<string> SMTPortfolio::unhandledQueries() std::vector<std::string> SMTPortfolio::unhandledQueries()
{ {
// This code assumes that the constructor guarantees that // This code assumes that the constructor guarantees that
// SmtLib2Interface is in position 0, if enabled. // SmtLib2Interface is in position 0, if enabled.
@ -158,7 +157,7 @@ bool SMTPortfolio::solverAnswered(CheckResult result)
return result == CheckResult::SATISFIABLE || result == CheckResult::UNSATISFIABLE; return result == CheckResult::SATISFIABLE || result == CheckResult::UNSATISFIABLE;
} }
string SMTPortfolio::dumpQuery(vector<Expression> const& _expressionsToEvaluate) std::string SMTPortfolio::dumpQuery(std::vector<Expression> const& _expressionsToEvaluate)
{ {
// This code assumes that the constructor guarantees that // This code assumes that the constructor guarantees that
// SmtLib2Interface is in position 0, if enabled. // SmtLib2Interface is in position 0, if enabled.

View File

@ -19,22 +19,20 @@
#include <libsmtutil/Sorts.h> #include <libsmtutil/Sorts.h>
using namespace std;
namespace solidity::smtutil namespace solidity::smtutil
{ {
shared_ptr<Sort> const SortProvider::boolSort{make_shared<Sort>(Kind::Bool)}; std::shared_ptr<Sort> const SortProvider::boolSort{std::make_shared<Sort>(Kind::Bool)};
shared_ptr<IntSort> const SortProvider::uintSort{make_shared<IntSort>(false)}; std::shared_ptr<IntSort> const SortProvider::uintSort{std::make_shared<IntSort>(false)};
shared_ptr<IntSort> const SortProvider::sintSort{make_shared<IntSort>(true)}; std::shared_ptr<IntSort> const SortProvider::sintSort{std::make_shared<IntSort>(true)};
shared_ptr<IntSort> SortProvider::intSort(bool _signed) std::shared_ptr<IntSort> SortProvider::intSort(bool _signed)
{ {
if (_signed) if (_signed)
return sintSort; return sintSort;
return uintSort; return uintSort;
} }
shared_ptr<BitVectorSort> const SortProvider::bitVectorSort{make_shared<BitVectorSort>(256)}; std::shared_ptr<BitVectorSort> const SortProvider::bitVectorSort{std::make_shared<BitVectorSort>(256)};
} }

View File

@ -23,21 +23,20 @@
#include <set> #include <set>
#include <stack> #include <stack>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::smtutil; using namespace solidity::smtutil;
Z3CHCInterface::Z3CHCInterface(optional<unsigned> _queryTimeout): Z3CHCInterface::Z3CHCInterface(std::optional<unsigned> _queryTimeout):
CHCSolverInterface(_queryTimeout), CHCSolverInterface(_queryTimeout),
m_z3Interface(make_unique<Z3Interface>(m_queryTimeout)), m_z3Interface(std::make_unique<Z3Interface>(m_queryTimeout)),
m_context(m_z3Interface->context()), m_context(m_z3Interface->context()),
m_solver(*m_context) m_solver(*m_context)
{ {
Z3_get_version( Z3_get_version(
&get<0>(m_version), &std::get<0>(m_version),
&get<1>(m_version), &std::get<1>(m_version),
&get<2>(m_version), &std::get<2>(m_version),
&get<3>(m_version) &std::get<3>(m_version)
); );
// These need to be set globally. // These need to be set globally.
@ -51,7 +50,7 @@ Z3CHCInterface::Z3CHCInterface(optional<unsigned> _queryTimeout):
setSpacerOptions(); setSpacerOptions();
} }
void Z3CHCInterface::declareVariable(string const& _name, SortPointer const& _sort) void Z3CHCInterface::declareVariable(std::string const& _name, SortPointer const& _sort)
{ {
smtAssert(_sort, ""); smtAssert(_sort, "");
m_z3Interface->declareVariable(_name, _sort); m_z3Interface->declareVariable(_name, _sort);
@ -62,7 +61,7 @@ void Z3CHCInterface::registerRelation(Expression const& _expr)
m_solver.register_relation(m_z3Interface->functions().at(_expr.name)); m_solver.register_relation(m_z3Interface->functions().at(_expr.name));
} }
void Z3CHCInterface::addRule(Expression const& _expr, string const& _name) void Z3CHCInterface::addRule(Expression const& _expr, std::string const& _name)
{ {
z3::expr rule = m_z3Interface->toZ3Expr(_expr); z3::expr rule = m_z3Interface->toZ3Expr(_expr);
if (m_z3Interface->constants().empty()) if (m_z3Interface->constants().empty())
@ -77,7 +76,7 @@ void Z3CHCInterface::addRule(Expression const& _expr, string const& _name)
} }
} }
tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> Z3CHCInterface::query(Expression const& _expr) std::tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> Z3CHCInterface::query(Expression const& _expr)
{ {
CheckResult result; CheckResult result;
try try
@ -90,7 +89,7 @@ tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> Z3CHCInterface::que
result = CheckResult::SATISFIABLE; result = CheckResult::SATISFIABLE;
// z3 version 4.8.8 modified Spacer to also return // z3 version 4.8.8 modified Spacer to also return
// proofs containing nonlinear clauses. // proofs containing nonlinear clauses.
if (m_version >= tuple(4, 8, 8, 0)) if (m_version >= std::tuple(4, 8, 8, 0))
{ {
auto proof = m_solver.get_answer(); auto proof = m_solver.get_answer();
return {result, Expression(true), cexGraph(proof)}; return {result, Expression(true), cexGraph(proof)};
@ -113,7 +112,7 @@ tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> Z3CHCInterface::que
} }
catch (z3::exception const& _err) catch (z3::exception const& _err)
{ {
set<string> msgs{ std::set<std::string> msgs{
/// Resource limit (rlimit) exhausted. /// Resource limit (rlimit) exhausted.
"max. resource limit exceeded", "max. resource limit exceeded",
/// User given timeout exhausted. /// User given timeout exhausted.
@ -178,13 +177,13 @@ CHCSolverInterface::CexGraph Z3CHCInterface::cexGraph(z3::expr const& _proof)
CexGraph graph; CexGraph graph;
stack<z3::expr> proofStack; std::stack<z3::expr> proofStack;
proofStack.push(_proof.arg(0)); proofStack.push(_proof.arg(0));
auto const& root = proofStack.top(); auto const& root = proofStack.top();
graph.nodes.emplace(root.id(), m_z3Interface->fromZ3Expr(fact(root))); graph.nodes.emplace(root.id(), m_z3Interface->fromZ3Expr(fact(root)));
set<unsigned> visited; std::set<unsigned> visited;
visited.insert(root.id()); visited.insert(root.id());
while (!proofStack.empty()) while (!proofStack.empty())
@ -227,16 +226,16 @@ z3::expr Z3CHCInterface::fact(z3::expr const& _node)
return _node.arg(_node.num_args() - 1); return _node.arg(_node.num_args() - 1);
} }
string Z3CHCInterface::name(z3::expr const& _predicate) std::string Z3CHCInterface::name(z3::expr const& _predicate)
{ {
smtAssert(_predicate.is_app(), ""); smtAssert(_predicate.is_app(), "");
return _predicate.decl().name().str(); return _predicate.decl().name().str();
} }
vector<string> Z3CHCInterface::arguments(z3::expr const& _predicate) std::vector<std::string> Z3CHCInterface::arguments(z3::expr const& _predicate)
{ {
smtAssert(_predicate.is_app(), ""); smtAssert(_predicate.is_app(), "");
vector<string> args; std::vector<std::string> args;
for (unsigned i = 0; i < _predicate.num_args(); ++i) for (unsigned i = 0; i < _predicate.num_args(); ++i)
args.emplace_back(_predicate.arg(i).to_string()); args.emplace_back(_predicate.arg(i).to_string());
return args; return args;

View File

@ -26,7 +26,6 @@
#include <libsmtutil/Z3Loader.h> #include <libsmtutil/Z3Loader.h>
#endif #endif
using namespace std;
using namespace solidity::smtutil; using namespace solidity::smtutil;
using namespace solidity::util; using namespace solidity::util;
@ -69,7 +68,7 @@ void Z3Interface::pop()
m_solver.pop(); m_solver.pop();
} }
void Z3Interface::declareVariable(string const& _name, SortPointer const& _sort) void Z3Interface::declareVariable(std::string const& _name, SortPointer const& _sort)
{ {
smtAssert(_sort, ""); smtAssert(_sort, "");
if (_sort->kind == Kind::Function) if (_sort->kind == Kind::Function)
@ -80,7 +79,7 @@ void Z3Interface::declareVariable(string const& _name, SortPointer const& _sort)
m_constants.emplace(_name, m_context.constant(_name.c_str(), z3Sort(*_sort))); m_constants.emplace(_name, m_context.constant(_name.c_str(), z3Sort(*_sort)));
} }
void Z3Interface::declareFunction(string const& _name, Sort const& _sort) void Z3Interface::declareFunction(std::string const& _name, Sort const& _sort)
{ {
smtAssert(_sort.kind == Kind::Function, ""); smtAssert(_sort.kind == Kind::Function, "");
FunctionSort fSort = dynamic_cast<FunctionSort const&>(_sort); FunctionSort fSort = dynamic_cast<FunctionSort const&>(_sort);
@ -95,10 +94,10 @@ void Z3Interface::addAssertion(Expression const& _expr)
m_solver.add(toZ3Expr(_expr)); m_solver.add(toZ3Expr(_expr));
} }
pair<CheckResult, vector<string>> Z3Interface::check(vector<Expression> const& _expressionsToEvaluate) std::pair<CheckResult, std::vector<std::string>> Z3Interface::check(std::vector<Expression> const& _expressionsToEvaluate)
{ {
CheckResult result; CheckResult result;
vector<string> values; std::vector<std::string> values;
try try
{ {
switch (m_solver.check()) switch (m_solver.check())
@ -123,7 +122,7 @@ pair<CheckResult, vector<string>> Z3Interface::check(vector<Expression> const& _
} }
catch (z3::exception const& _err) catch (z3::exception const& _err)
{ {
set<string> msgs{ std::set<std::string> msgs{
/// Resource limit (rlimit) exhausted. /// Resource limit (rlimit) exhausted.
"max. resource limit exceeded", "max. resource limit exceeded",
/// User given timeout exhausted. /// User given timeout exhausted.
@ -137,7 +136,7 @@ pair<CheckResult, vector<string>> Z3Interface::check(vector<Expression> const& _
values.clear(); values.clear();
} }
return make_pair(result, values); return std::make_pair(result, values);
} }
z3::expr Z3Interface::toZ3Expr(Expression const& _expr) z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
@ -150,7 +149,7 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
try try
{ {
string const& n = _expr.name; std::string const& n = _expr.name;
if (m_functions.count(n)) if (m_functions.count(n))
return m_functions.at(n)(arguments); return m_functions.at(n)(arguments);
else if (m_constants.count(n)) else if (m_constants.count(n))
@ -166,7 +165,7 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
return m_context.bool_val(false); return m_context.bool_val(false);
else if (_expr.sort->kind == Kind::Sort) else if (_expr.sort->kind == Kind::Sort)
{ {
auto sortSort = dynamic_pointer_cast<SortSort>(_expr.sort); auto sortSort = std::dynamic_pointer_cast<SortSort>(_expr.sort);
smtAssert(sortSort, ""); smtAssert(sortSort, "");
return m_context.constant(n.c_str(), z3Sort(*sortSort->inner)); return m_context.constant(n.c_str(), z3Sort(*sortSort->inner));
} }
@ -233,7 +232,7 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
} }
else if (n == "bv2int") else if (n == "bv2int")
{ {
auto intSort = dynamic_pointer_cast<IntSort>(_expr.sort); auto intSort = std::dynamic_pointer_cast<IntSort>(_expr.sort);
smtAssert(intSort, ""); smtAssert(intSort, "");
return z3::bv2int(arguments[0], intSort->isSigned); return z3::bv2int(arguments[0], intSort->isSigned);
} }
@ -243,9 +242,9 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
return z3::store(arguments[0], arguments[1], arguments[2]); return z3::store(arguments[0], arguments[1], arguments[2]);
else if (n == "const_array") else if (n == "const_array")
{ {
shared_ptr<SortSort> sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments[0].sort); std::shared_ptr<SortSort> sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments[0].sort);
smtAssert(sortSort, ""); smtAssert(sortSort, "");
auto arraySort = dynamic_pointer_cast<ArraySort>(sortSort->inner); auto arraySort = std::dynamic_pointer_cast<ArraySort>(sortSort->inner);
smtAssert(arraySort && arraySort->domain, ""); smtAssert(arraySort && arraySort->domain, "");
return z3::const_array(z3Sort(*arraySort->domain), arguments[1]); return z3::const_array(z3Sort(*arraySort->domain), arguments[1]);
} }
@ -285,7 +284,7 @@ Expression Z3Interface::fromZ3Expr(z3::expr const& _expr)
if (_expr.is_quantifier()) if (_expr.is_quantifier())
{ {
string quantifierName; std::string quantifierName;
if (_expr.is_exists()) if (_expr.is_exists())
quantifierName = "exists"; quantifierName = "exists";
else if (_expr.is_forall()) else if (_expr.is_forall())
@ -297,7 +296,7 @@ Expression Z3Interface::fromZ3Expr(z3::expr const& _expr)
return Expression(quantifierName, {fromZ3Expr(_expr.body())}, sort); return Expression(quantifierName, {fromZ3Expr(_expr.body())}, sort);
} }
smtAssert(_expr.is_app(), ""); smtAssert(_expr.is_app(), "");
vector<Expression> arguments; std::vector<Expression> arguments;
for (unsigned i = 0; i < _expr.num_args(); ++i) for (unsigned i = 0; i < _expr.num_args(); ++i)
arguments.push_back(fromZ3Expr(_expr.arg(i))); arguments.push_back(fromZ3Expr(_expr.arg(i)));
@ -370,12 +369,12 @@ Expression Z3Interface::fromZ3Expr(z3::expr const& _expr)
return Expression::store(arguments[0], arguments[1], arguments[2]); return Expression::store(arguments[0], arguments[1], arguments[2]);
else if (kind == Z3_OP_CONST_ARRAY) else if (kind == Z3_OP_CONST_ARRAY)
{ {
auto sortSort = make_shared<SortSort>(fromZ3Sort(_expr.get_sort())); auto sortSort = std::make_shared<SortSort>(fromZ3Sort(_expr.get_sort()));
return Expression::const_array(Expression(sortSort), arguments[0]); return Expression::const_array(Expression(sortSort), arguments[0]);
} }
else if (kind == Z3_OP_DT_CONSTRUCTOR) else if (kind == Z3_OP_DT_CONSTRUCTOR)
{ {
auto sortSort = make_shared<SortSort>(fromZ3Sort(_expr.get_sort())); auto sortSort = std::make_shared<SortSort>(fromZ3Sort(_expr.get_sort()));
return Expression::tuple_constructor(Expression(sortSort), arguments); return Expression::tuple_constructor(Expression(sortSort), arguments);
} }
else if (kind == Z3_OP_DT_ACCESSOR) else if (kind == Z3_OP_DT_ACCESSOR)
@ -412,12 +411,12 @@ z3::sort Z3Interface::z3Sort(Sort const& _sort)
case Kind::Tuple: case Kind::Tuple:
{ {
auto const& tupleSort = dynamic_cast<TupleSort const&>(_sort); auto const& tupleSort = dynamic_cast<TupleSort const&>(_sort);
vector<char const*> cMembers; std::vector<char const*> cMembers;
for (auto const& member: tupleSort.members) for (auto const& member: tupleSort.members)
cMembers.emplace_back(member.c_str()); cMembers.emplace_back(member.c_str());
/// Using this instead of the function below because with that one /// Using this instead of the function below because with that one
/// we can't use `&sorts[0]` here. /// we can't use `&sorts[0]` here.
vector<z3::sort> sorts; std::vector<z3::sort> sorts;
for (auto const& sort: tupleSort.components) for (auto const& sort: tupleSort.components)
sorts.push_back(z3Sort(*sort)); sorts.push_back(z3Sort(*sort));
z3::func_decl_vector projs(m_context); z3::func_decl_vector projs(m_context);
@ -439,7 +438,7 @@ z3::sort Z3Interface::z3Sort(Sort const& _sort)
return m_context.int_sort(); return m_context.int_sort();
} }
z3::sort_vector Z3Interface::z3Sort(vector<SortPointer> const& _sorts) z3::sort_vector Z3Interface::z3Sort(std::vector<SortPointer> const& _sorts)
{ {
z3::sort_vector z3Sorts(m_context); z3::sort_vector z3Sorts(m_context);
for (auto const& _sort: _sorts) for (auto const& _sort: _sorts)
@ -454,27 +453,27 @@ SortPointer Z3Interface::fromZ3Sort(z3::sort const& _sort)
if (_sort.is_int()) if (_sort.is_int())
return SortProvider::sintSort; return SortProvider::sintSort;
if (_sort.is_bv()) if (_sort.is_bv())
return make_shared<BitVectorSort>(_sort.bv_size()); return std::make_shared<BitVectorSort>(_sort.bv_size());
if (_sort.is_array()) if (_sort.is_array())
return make_shared<ArraySort>(fromZ3Sort(_sort.array_domain()), fromZ3Sort(_sort.array_range())); return std::make_shared<ArraySort>(fromZ3Sort(_sort.array_domain()), fromZ3Sort(_sort.array_range()));
if (_sort.is_datatype()) if (_sort.is_datatype())
{ {
auto name = _sort.name().str(); auto name = _sort.name().str();
auto constructor = z3::func_decl(m_context, Z3_get_tuple_sort_mk_decl(m_context, _sort)); auto constructor = z3::func_decl(m_context, Z3_get_tuple_sort_mk_decl(m_context, _sort));
vector<string> memberNames; std::vector<std::string> memberNames;
vector<SortPointer> memberSorts; std::vector<SortPointer> memberSorts;
for (unsigned i = 0; i < constructor.arity(); ++i) for (unsigned i = 0; i < constructor.arity(); ++i)
{ {
auto accessor = z3::func_decl(m_context, Z3_get_tuple_sort_field_decl(m_context, _sort, i)); auto accessor = z3::func_decl(m_context, Z3_get_tuple_sort_field_decl(m_context, _sort, i));
memberNames.push_back(accessor.name().str()); memberNames.push_back(accessor.name().str());
memberSorts.push_back(fromZ3Sort(accessor.range())); memberSorts.push_back(fromZ3Sort(accessor.range()));
} }
return make_shared<TupleSort>(name, memberNames, memberSorts); return std::make_shared<TupleSort>(name, memberNames, memberSorts);
} }
smtAssert(false, ""); smtAssert(false, "");
} }
vector<SortPointer> Z3Interface::fromZ3Sort(z3::sort_vector const& _sorts) std::vector<SortPointer> Z3Interface::fromZ3Sort(z3::sort_vector const& _sorts)
{ {
return applyMap(_sorts, [this](auto const& sort) { return fromZ3Sort(sort); }); return applyMap(_sorts, [this](auto const& sort) { return fromZ3Sort(sort); });
} }

View File

@ -27,7 +27,6 @@
#endif #endif
#include <dlfcn.h> #include <dlfcn.h>
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::smtutil; using namespace solidity::smtutil;
@ -41,7 +40,7 @@ void* Z3Loader::loadSymbol(char const* _name) const
{ {
smtAssert(m_handle, "Attempted to use dynamically loaded Z3, even though it is not available."); smtAssert(m_handle, "Attempted to use dynamically loaded Z3, even though it is not available.");
void* sym = dlsym(m_handle, _name); void* sym = dlsym(m_handle, _name);
smtAssert(sym, string("Symbol \"") + _name + "\" not found in libz3.so"); smtAssert(sym, std::string("Symbol \"") + _name + "\" not found in libz3.so");
return sym; return sym;
} }
@ -59,7 +58,7 @@ bool Z3Loader::available() const
Z3Loader::Z3Loader() Z3Loader::Z3Loader()
{ {
string libname{"libz3.so." + to_string(Z3_MAJOR_VERSION) + "." + to_string(Z3_MINOR_VERSION)}; std::string libname{"libz3.so." + std::to_string(Z3_MAJOR_VERSION) + "." + std::to_string(Z3_MINOR_VERSION)};
m_handle = dlmopen(LM_ID_NEWLM, libname.c_str(), RTLD_NOW); m_handle = dlmopen(LM_ID_NEWLM, libname.c_str(), RTLD_NOW);
} }

View File

@ -32,7 +32,6 @@
#include "license.h" #include "license.h"
using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::util; using namespace solidity::util;
@ -42,21 +41,21 @@ using solidity::frontend::StandardCompiler;
namespace namespace
{ {
// The strings in this list must not be resized after they have been added here (via solidity_alloc()), because // The std::strings in this list must not be resized after they have been added here (via solidity_alloc()), because
// this may potentially change the pointer that was passed to the caller from solidity_alloc(). // this may potentially change the pointer that was passed to the caller from solidity_alloc().
static list<string> solidityAllocations; static std::list<std::string> solidityAllocations;
/// Find the equivalent to @p _data in the list of allocations of solidity_alloc(), /// Find the equivalent to @p _data in the list of allocations of solidity_alloc(),
/// removes it from the list and returns its value. /// removes it from the list and returns its value.
/// ///
/// If any invalid argument is being passed, it is considered a programming error /// If any invalid argument is being passed, it is considered a programming error
/// on the caller-side and hence, will call abort() then. /// on the caller-side and hence, will call abort() then.
string takeOverAllocation(char const* _data) std::string takeOverAllocation(char const* _data)
{ {
for (auto iter = begin(solidityAllocations); iter != end(solidityAllocations); ++iter) for (auto iter = begin(solidityAllocations); iter != end(solidityAllocations); ++iter)
if (iter->data() == _data) if (iter->data() == _data)
{ {
string chunk = std::move(*iter); std::string chunk = std::move(*iter);
solidityAllocations.erase(iter); solidityAllocations.erase(iter);
return chunk; return chunk;
} }
@ -64,11 +63,11 @@ string takeOverAllocation(char const* _data)
abort(); abort();
} }
/// Resizes a std::string to the proper length based on the occurrence of a zero terminator. /// Resizes a std::std::string to the proper length based on the occurrence of a zero terminator.
void truncateCString(string& _data) void truncateCString(std::string& _data)
{ {
size_t pos = _data.find('\0'); size_t pos = _data.find('\0');
if (pos != string::npos) if (pos != std::string::npos)
_data.resize(pos); _data.resize(pos);
} }
@ -77,7 +76,7 @@ ReadCallback::Callback wrapReadCallback(CStyleReadFileCallback _readCallback, vo
ReadCallback::Callback readCallback; ReadCallback::Callback readCallback;
if (_readCallback) if (_readCallback)
{ {
readCallback = [=](string const& _kind, string const& _data) readCallback = [=](std::string const& _kind, std::string const& _data)
{ {
char* contents_c = nullptr; char* contents_c = nullptr;
char* error_c = nullptr; char* error_c = nullptr;
@ -106,7 +105,7 @@ ReadCallback::Callback wrapReadCallback(CStyleReadFileCallback _readCallback, vo
return readCallback; return readCallback;
} }
string compile(string _input, CStyleReadFileCallback _readCallback, void* _readContext) std::string compile(std::string _input, CStyleReadFileCallback _readCallback, void* _readContext)
{ {
StandardCompiler compiler(wrapReadCallback(_readCallback, _readContext)); StandardCompiler compiler(wrapReadCallback(_readCallback, _readContext));
return compiler.compile(std::move(_input)); return compiler.compile(std::move(_input));
@ -118,7 +117,7 @@ extern "C"
{ {
extern char const* solidity_license() noexcept extern char const* solidity_license() noexcept
{ {
static string fullLicenseText = otherLicenses + licenseText; static std::string fullLicenseText = otherLicenses + licenseText;
return fullLicenseText.c_str(); return fullLicenseText.c_str();
} }

View File

@ -2295,13 +2295,13 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
} }
case DataLocation::Memory: case DataLocation::Memory:
{ {
string const memAddress = string const indexAccessFunction = m_utils.memoryArrayIndexAccessFunction(arrayType);
m_utils.memoryArrayIndexAccessFunction(arrayType) + string const baseRef = IRVariable(_indexAccess.baseExpression()).part("mpos").name();
"(" + string const indexExpression = expressionAsType(
IRVariable(_indexAccess.baseExpression()).part("mpos").name() + *_indexAccess.indexExpression(),
", " + *TypeProvider::uint256()
expressionAsType(*_indexAccess.indexExpression(), *TypeProvider::uint256()) + );
")"; string const memAddress = indexAccessFunction + "(" + baseRef + ", " + indexExpression + ")";
setLValue(_indexAccess, IRLValue{ setLValue(_indexAccess, IRLValue{
*arrayType.baseType(), *arrayType.baseType(),
@ -2311,28 +2311,28 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess)
} }
case DataLocation::CallData: case DataLocation::CallData:
{ {
string indexAccessFunction = m_utils.calldataArrayIndexAccessFunction(arrayType); string const indexAccessFunction = m_utils.calldataArrayIndexAccessFunction(arrayType);
string const indexAccessFunctionCall = string const baseRef = IRVariable(_indexAccess.baseExpression()).commaSeparatedList();
indexAccessFunction + string const indexExpression = expressionAsType(
"(" + *_indexAccess.indexExpression(),
IRVariable(_indexAccess.baseExpression()).commaSeparatedList() + *TypeProvider::uint256()
", " + );
expressionAsType(*_indexAccess.indexExpression(), *TypeProvider::uint256()) + string const calldataAddress = indexAccessFunction + "(" + baseRef + ", " + indexExpression + ")";
")";
if (arrayType.isByteArrayOrString()) if (arrayType.isByteArrayOrString())
define(_indexAccess) << define(_indexAccess) <<
m_utils.cleanupFunction(*arrayType.baseType()) << m_utils.cleanupFunction(*arrayType.baseType()) <<
"(calldataload(" << "(calldataload(" <<
indexAccessFunctionCall << calldataAddress <<
"))\n"; "))\n";
else if (arrayType.baseType()->isValueType()) else if (arrayType.baseType()->isValueType())
define(_indexAccess) << define(_indexAccess) <<
m_utils.readFromCalldata(*arrayType.baseType()) << m_utils.readFromCalldata(*arrayType.baseType()) <<
"(" << "(" <<
indexAccessFunctionCall << calldataAddress <<
")\n"; ")\n";
else else
define(_indexAccess) << indexAccessFunctionCall << "\n"; define(_indexAccess) << calldataAddress << "\n";
break; break;
} }
} }

View File

@ -5,8 +5,10 @@ const fs = require('fs')
const compiler = require('solc') const compiler = require('solc')
SETTINGS_PRESETS = { SETTINGS_PRESETS = {
'legacy-optimize': {optimize: true}, 'legacy-optimize': {optimize: true, viaIR: false},
'legacy-no-optimize': {optimize: false}, 'legacy-no-optimize': {optimize: false, viaIR: false},
'via-ir-optimize': {optimize: true, viaIR: true},
'via-ir-no-optimize': {optimize: false, viaIR: true},
} }
function loadSource(sourceFileName, stripSMTPragmas) function loadSource(sourceFileName, stripSMTPragmas)
@ -67,6 +69,8 @@ for (const preset of presets)
}, },
settings: { settings: {
optimizer: {enabled: settings.optimize}, optimizer: {enabled: settings.optimize},
// NOTE: We omit viaIR rather than set it to false to handle older versions that don't have it.
viaIR: settings.viaIR ? true : undefined,
outputSelection: {'*': {'*': ['evm.bytecode.object', 'metadata']}} outputSelection: {'*': {'*': ['evm.bytecode.object', 'metadata']}}
} }
} }
@ -96,7 +100,7 @@ for (const preset of presets)
// JSON interface still returns contract metadata in case of an internal compiler error while // JSON interface still returns contract metadata in case of an internal compiler error while
// CLI interface does not. To make reports comparable we must force this case to be detected as // CLI interface does not. To make reports comparable we must force this case to be detected as
// an error in both cases. // an error in both cases.
if (['UnimplementedFeatureError', 'CompilerError', 'CodeGenerationError'].includes(error['type'])) if (['UnimplementedFeatureError', 'CompilerError', 'CodeGenerationError', 'YulException'].includes(error['type']))
{ {
internalCompilerError = true internalCompilerError = true
break break

View File

@ -29,6 +29,8 @@ class CompilerInterface(Enum):
class SettingsPreset(Enum): class SettingsPreset(Enum):
LEGACY_OPTIMIZE = 'legacy-optimize' LEGACY_OPTIMIZE = 'legacy-optimize'
LEGACY_NO_OPTIMIZE = 'legacy-no-optimize' LEGACY_NO_OPTIMIZE = 'legacy-no-optimize'
VIA_IR_OPTIMIZE = 'via-ir-optimize'
VIA_IR_NO_OPTIMIZE = 'via-ir-no-optimize'
class SMTUse(Enum): class SMTUse(Enum):
@ -40,12 +42,15 @@ class SMTUse(Enum):
@dataclass(frozen=True) @dataclass(frozen=True)
class CompilerSettings: class CompilerSettings:
optimize: bool optimize: bool
via_ir: bool
@staticmethod @staticmethod
def from_preset(preset: SettingsPreset): def from_preset(preset: SettingsPreset):
return { return {
SettingsPreset.LEGACY_OPTIMIZE: CompilerSettings(optimize=True), SettingsPreset.LEGACY_OPTIMIZE: CompilerSettings(optimize=True, via_ir=False),
SettingsPreset.LEGACY_NO_OPTIMIZE: CompilerSettings(optimize=False), SettingsPreset.LEGACY_NO_OPTIMIZE: CompilerSettings(optimize=False, via_ir=False),
SettingsPreset.VIA_IR_OPTIMIZE: CompilerSettings(optimize=True, via_ir=True),
SettingsPreset.VIA_IR_NO_OPTIMIZE: CompilerSettings(optimize=False, via_ir=True),
}[preset] }[preset]
@ -152,7 +157,7 @@ def parse_standard_json_output(source_file_name: Path, standard_json_output: str
# CLI interface does not. To make reports comparable we must force this case to be detected as # CLI interface does not. To make reports comparable we must force this case to be detected as
# an error in both cases. # an error in both cases.
internal_compiler_error = any( internal_compiler_error = any(
error['type'] in ['UnimplementedFeatureError', 'CompilerError', 'CodeGenerationError'] error['type'] in ['UnimplementedFeatureError', 'CompilerError', 'CodeGenerationError', 'YulException']
for error in decoded_json_output.get('errors', {}) for error in decoded_json_output.get('errors', {})
) )
@ -224,6 +229,8 @@ def prepare_compiler_input(
}, },
'settings': { 'settings': {
'optimizer': {'enabled': settings.optimize}, 'optimizer': {'enabled': settings.optimize},
# NOTE: We omit viaIR rather than set it to false to handle older versions that don't have it.
**({'viaIR': True} if settings.via_ir else {}),
'outputSelection': {'*': {'*': ['evm.bytecode.object', 'metadata']}}, 'outputSelection': {'*': {'*': ['evm.bytecode.object', 'metadata']}},
} }
} }
@ -243,6 +250,8 @@ def prepare_compiler_input(
compiler_options.append('--optimize') compiler_options.append('--optimize')
elif force_no_optimize_yul: elif force_no_optimize_yul:
compiler_options.append('--no-optimize-yul') compiler_options.append('--no-optimize-yul')
if settings.via_ir:
compiler_options.append('--via-ir')
if smt_use == SMTUse.DISABLE: if smt_use == SMTUse.DISABLE:
compiler_options += ['--model-checker-engine', 'none'] compiler_options += ['--model-checker-engine', 'none']

View File

@ -20,6 +20,13 @@ EXCLUDE_FILES=(
EXCLUDE_FILES_JOINED=$(printf "%s\|" "${EXCLUDE_FILES[@]}") EXCLUDE_FILES_JOINED=$(printf "%s\|" "${EXCLUDE_FILES[@]}")
EXCLUDE_FILES_JOINED=${EXCLUDE_FILES_JOINED%??} EXCLUDE_FILES_JOINED=${EXCLUDE_FILES_JOINED%??}
NAMESPACE_STD_FREE_FILES=(
libevmasm/*
liblangutil/*
libsmtutil/*
libsolc/*
)
( (
REPO_ROOT="$(dirname "$0")"/.. REPO_ROOT="$(dirname "$0")"/..
cd "$REPO_ROOT" || exit 1 cd "$REPO_ROOT" || exit 1
@ -58,6 +65,9 @@ FORMATERROR=$(
# unqualified move()/forward() checks, i.e. make sure that std::move() and std::forward() are used instead of move() and forward() # unqualified move()/forward() checks, i.e. make sure that std::move() and std::forward() are used instead of move() and forward()
preparedGrep "move\(.+\)" | grep -v "std::move" | grep -E "[^a-z]move" preparedGrep "move\(.+\)" | grep -v "std::move" | grep -E "[^a-z]move"
preparedGrep "forward\(.+\)" | grep -v "std::forward" | grep -E "[^a-z]forward" preparedGrep "forward\(.+\)" | grep -v "std::forward" | grep -E "[^a-z]forward"
# make sure `using namespace std` is not used in INCLUDE_DIRECTORIES
# shellcheck disable=SC2068,SC2068
grep -nIE -d skip "using namespace std;" ${NAMESPACE_STD_FREE_FILES[@]}
) | grep -E -v -e "^[a-zA-Z\./]*:[0-9]*:\s*\/(\/|\*)" -e "^test/" || true ) | grep -E -v -e "^[a-zA-Z\./]*:[0-9]*:\s*\/(\/|\*)" -e "^test/" || true
) )

View File

@ -83,10 +83,9 @@ function zeppelin_test
sed -i "s|it(\('reverts if index is greater than supply'\)|it.skip(\1|g" test/token/ERC721/ERC721.behavior.js sed -i "s|it(\('reverts if index is greater than supply'\)|it.skip(\1|g" test/token/ERC721/ERC721.behavior.js
sed -i "s|it(\('burns all tokens'\)|it.skip(\1|g" test/token/ERC721/ERC721.behavior.js sed -i "s|it(\('burns all tokens'\)|it.skip(\1|g" test/token/ERC721/ERC721.behavior.js
sed -i "s|it(\('guards transfer against invalid user'\)|it.skip(\1|g" test/access/Ownable2Step.test.js sed -i "s|it(\('guards transfer against invalid user'\)|it.skip(\1|g" test/access/Ownable2Step.test.js
sed -i "s|it(\('reverting initialization'\)|it.skip(\1|g" test/proxy/beacon/BeaconProxy.test.js sed -i "s|it(\('reverting initialization function'\)|it.skip(\1|g" test/proxy/beacon/BeaconProxy.test.js
sed -i "s|describe(\('reverting initialization'\)|describe.skip(\1|g" test/proxy/Proxy.behaviour.js sed -i "s|describe(\('reverting initialization'\)|describe.skip(\1|g" test/proxy/Proxy.behaviour.js
sed -i "s|it(\('does not allow remote callback'\)|it.skip(\1|g" test/security/ReentrancyGuard.test.js sed -i "s|it(\('does not allow remote callback'\)|it.skip(\1|g" test/security/ReentrancyGuard.test.js
sed -i "s|shouldBehaveLikeAccessControlDefaultAdminRules|\/\/&|" test/access/AccessControlDefaultAdminRules.test.js
# TODO: Remove when hardhat properly handle reverts of custom errors with via-ir enabled # TODO: Remove when hardhat properly handle reverts of custom errors with via-ir enabled
# and/or open-zeppelin fix https://github.com/OpenZeppelin/openzeppelin-contracts/issues/4349 # and/or open-zeppelin fix https://github.com/OpenZeppelin/openzeppelin-contracts/issues/4349

View File

@ -265,6 +265,7 @@ class TestPrepareCompilerInput(PrepareReportTestBase):
}, },
'settings': { 'settings': {
'optimizer': {'enabled': True}, 'optimizer': {'enabled': True},
'viaIR': True,
'outputSelection': {'*': {'*': ['evm.bytecode.object', 'metadata']}}, 'outputSelection': {'*': {'*': ['evm.bytecode.object', 'metadata']}},
'modelChecker': {'engine': 'none'}, 'modelChecker': {'engine': 'none'},
} }
@ -273,7 +274,7 @@ class TestPrepareCompilerInput(PrepareReportTestBase):
(command_line, compiler_input) = prepare_compiler_input( (command_line, compiler_input) = prepare_compiler_input(
Path('solc'), Path('solc'),
SMT_CONTRACT_WITH_MIXED_NEWLINES_SOL_PATH, SMT_CONTRACT_WITH_MIXED_NEWLINES_SOL_PATH,
preset=SettingsPreset.LEGACY_OPTIMIZE, preset=SettingsPreset.VIA_IR_OPTIMIZE,
force_no_optimize_yul=False, force_no_optimize_yul=False,
interface=CompilerInterface.STANDARD_JSON, interface=CompilerInterface.STANDARD_JSON,
smt_use=SMTUse.DISABLE, smt_use=SMTUse.DISABLE,
@ -317,7 +318,7 @@ class TestPrepareCompilerInput(PrepareReportTestBase):
(command_line, compiler_input) = prepare_compiler_input( (command_line, compiler_input) = prepare_compiler_input(
Path('solc'), Path('solc'),
SMT_SMOKE_TEST_SOL_PATH, SMT_SMOKE_TEST_SOL_PATH,
preset=SettingsPreset.LEGACY_OPTIMIZE, preset=SettingsPreset.VIA_IR_OPTIMIZE,
force_no_optimize_yul=False, force_no_optimize_yul=False,
interface=CompilerInterface.CLI, interface=CompilerInterface.CLI,
smt_use=SMTUse.PRESERVE, smt_use=SMTUse.PRESERVE,
@ -326,7 +327,7 @@ class TestPrepareCompilerInput(PrepareReportTestBase):
self.assertEqual( self.assertEqual(
command_line, command_line,
['solc', str(SMT_SMOKE_TEST_SOL_PATH), '--bin', '--optimize'], ['solc', str(SMT_SMOKE_TEST_SOL_PATH), '--bin', '--optimize', '--via-ir'],
) )
self.assertEqual(compiler_input, SMT_SMOKE_TEST_SOL_CODE) self.assertEqual(compiler_input, SMT_SMOKE_TEST_SOL_CODE)