diff --git a/.github/workflows/bindgen.yml b/.github/workflows/bindgen.yml index 7e9c254e83..bd1489911e 100644 --- a/.github/workflows/bindgen.yml +++ b/.github/workflows/bindgen.yml @@ -12,50 +12,52 @@ on: - main jobs: - rustfmt-clippy: + rustfmt: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 - - name: Install stable + - name: Install nightly uses: dtolnay/rust-toolchain@master with: - # TODO: Should ideally be stable, but we use some nightly-only - # features. toolchain: nightly - components: rustfmt, clippy + components: rustfmt - name: Run rustfmt - run: cargo fmt -- --check + run: cargo +nightly fmt -- --check + + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 - name: Run clippy - run: cargo clippy --tests + run: cargo clippy --all-targets --workspace --exclude bindgen-integration --exclude tests_expectations -- -D warnings msrv: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: Read crate metadata + id: metadata + run: echo "rust-version=$(sed -ne 's/rust-version *= *\"\(.*\)\"/\1/p' Cargo.toml)" >> $GITHUB_OUTPUT + - name: Install msrv for lib uses: dtolnay/rust-toolchain@master with: - # MSRV below is documented in Cargo.toml and README.md, please update those if you - # change this. - toolchain: 1.70.0 + toolchain: ${{ steps.metadata.outputs.rust-version }} - name: Test lib with msrv - run: cargo +1.70.0 test --package bindgen + run: cargo +${{ steps.metadata.outputs.rust-version }} test --package bindgen - name: Install msrv for cli uses: dtolnay/rust-toolchain@master with: - # MSRV below is documented in Cargo.toml and README.md, please update those if you - # change this. - toolchain: 1.70.0 + toolchain: ${{ steps.metadata.outputs.rust-version }} - name: Test cli with msrv - run: cargo +1.70.0 build --package bindgen-cli + run: cargo +${{ steps.metadata.outputs.rust-version }} build --package bindgen-cli minimal: runs-on: ubuntu-latest @@ -64,12 +66,7 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install stable - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - - - name: Check without default features + - name: Check without default features run: cargo check -p bindgen --no-default-features --features=runtime docs: @@ -79,12 +76,7 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install stable - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - - - name: Generate documentation for `bindgen` + - name: Generate documentation for `bindgen` run: cargo doc --document-private-items --no-deps -p bindgen - name: Generate documentation for `bindgen-cli` @@ -95,11 +87,6 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install stable - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - # TODO: Actually run quickchecks once `bindgen` is reliable enough. - name: Build quickcheck tests run: cd bindgen-tests/tests/quickchecking && cargo test @@ -108,29 +95,25 @@ jobs: runs-on: ${{matrix.os}} strategy: matrix: - os: [ubuntu-latest, macos-12] + os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest] steps: - uses: actions/checkout@v4 - - name: Install stable - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - - name: Test expectations run: cd bindgen-tests/tests/expectations && cargo test test: - runs-on: ${{matrix.os}} + runs-on: ${{matrix.platform.os}} strategy: matrix: - os: [ubuntu-latest] - target: - - debian: null - cross: null - rust: null + platform: + - os: ubuntu-latest + libtinfo: libtinfo5_6.3-2ubuntu0.1_amd64.deb + ubuntu_repo: https://mirrors.kernel.org/ubuntu/pool/universe/n/ncurses/ + - os: ubuntu-24.04-arm + libtinfo: libtinfo5_6.3-2ubuntu0.1_arm64.deb + ubuntu_repo: https://ports.ubuntu.com/ubuntu-ports/pool/universe/n/ncurses/ llvm_version: ["9.0", "16.0"] - main_tests: [1] release_build: [0, 1] no_default_features: [0, 1] # FIXME: There are no pre-built static libclang libraries, so the @@ -141,91 +124,48 @@ jobs: include: # Test with extra asserts + docs just with latest llvm versions to # prevent explosion - - os: ubuntu-latest + - platform: + os: ubuntu-latest + libtinfo: libtinfo5_6.3-2ubuntu0.1_amd64.deb + ubuntu_repo: https://mirrors.kernel.org/ubuntu/pool/universe/n/ncurses/ llvm_version: "16.0" release_build: 0 no_default_features: 0 feature_extra_asserts: 1 - # FIXME: Seems installing multiarch packages fails: - # - # https://github.com/rust-lang/rust-bindgen/pull/2037/checks?check_run_id=2441799333 - # - # - os: ubuntu-latest - # target: - # debian: arm64 - # cross: aarch64-linux-gnu - # rust: aarch64-unknown-linux-gnu - # llvm_version: "16.0" - # main_tests: 0 - # release_build: 0 - # feature_extra_asserts: 0 - # Ensure stuff works on macos too - # FIXME: Ideally should use the latest llvm version, but llvm doesn't - # provide releases for x86-64 macOS anymore which is what the runner uses. - # - - os: macos-12 - llvm_version: "9.0" + - platform: + os: macos-latest + llvm_version: "16.0" release_build: 0 no_default_features: 0 feature_extra_asserts: 0 steps: - uses: actions/checkout@v4 - - name: Install multiarch packages - if: matrix.target.debian - run: | - sudo apt-get install binfmt-support qemu-user-static gcc-${{matrix.target.cross}} g++-${{matrix.target.cross}} - source /etc/lsb-release - sudo tee /etc/apt/sources.list </dev/null - deb [arch=${{matrix.target.debian}}] http://ports.ubuntu.com/ubuntu-ports/ $DISTRIB_CODENAME main - deb [arch=${{matrix.target.debian}}] http://ports.ubuntu.com/ubuntu-ports/ $DISTRIB_CODENAME-updates main - deb [arch=${{matrix.target.debian}}] http://ports.ubuntu.com/ubuntu-ports/ $DISTRIB_CODENAME-backports main - deb [arch=${{matrix.target.debian}}] http://ports.ubuntu.com/ubuntu-ports/ $DISTRIB_CODENAME-security main - EOF - sudo dpkg --add-architecture ${{matrix.target.debian}} - sudo apt-get update - sudo apt-get install libc6:${{matrix.target.debian}} libstdc++6:${{matrix.target.debian}} - - name: Install stable uses: dtolnay/rust-toolchain@master with: toolchain: stable - target: ${{matrix.target.rust}} - name: Install libtinfo - if: matrix.os == 'ubuntu-latest' + if: startsWith(matrix.platform.os, 'ubuntu') run: | - sudo apt-get update - sudo apt-get install libtinfo5 + wget ${{matrix.platform.ubuntu_repo}}${{matrix.platform.libtinfo}} + sudo dpkg -i ${{matrix.platform.libtinfo}} + - name: Install LLVM and Clang + uses: KyleMayes/install-llvm-action@v2.0.5 + with: + version: ${{matrix.llvm_version}} - name: Run all the tests env: - GITHUB_ACTIONS_OS: ${{matrix.os}} - RUST_CROSS_COMPILER: ${{matrix.target.cross}} - RUST_TARGET: ${{matrix.target.rust}} - LLVM_VERSION: ${{matrix.llvm_version}} - BINDGEN_MAIN_TESTS: ${{matrix.main_tests}} + GITHUB_ACTIONS_OS: ${{matrix.platform.os}} BINDGEN_RELEASE_BUILD: ${{matrix.release_build}} BINDGEN_FEATURE_RUNTIME: ${{matrix.feature_runtime}} BINDGEN_FEATURE_EXTRA_ASSERTS: ${{matrix.feature_extra_asserts}} BINDGEN_NO_DEFAULT_FEATURES: ${{matrix.no_default_features}} + BINDGEN_RUST_FOR_LINUX_TEST: ${{startsWith(matrix.platform.os, 'ubuntu') && matrix.llvm_version == '16.0' && matrix.feature_extra_asserts == 0 && 1 || 0}} run: ./ci/test.sh - check-cfg: - runs-on: ubuntu-latest - env: - RUSTFLAGS: -D warnings - steps: - - uses: actions/checkout@v4 - - - name: Install nightly - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly - - - name: Check cfg - run: cargo check -Z unstable-options -Z check-cfg - test-book: runs-on: ubuntu-latest steps: @@ -238,12 +178,27 @@ jobs: ./mdbook build book ./mdbook test book + # FIXME(pvdrz): this should be done inside `bindgen-test` instead + test-no-headers: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Test `--help` + run: cargo run -- --help + + - name: Test `--version` + run: cargo run -- --version + + - name: Test `--generate-shell-completions` + run: cargo run -- --generate-shell-completions=bash + # One job that "summarizes" the success state of this pipeline. This can then # be added to branch protection, rather than having to add each job # separately. success: runs-on: ubuntu-latest - needs: [rustfmt-clippy, msrv, minimal, docs, quickchecking, test-expectations, test, check-cfg, test-book] + needs: [rustfmt, clippy, msrv, minimal, docs, quickchecking, test-expectations, test, test-book, test-no-headers] # GitHub branch protection is exceedingly silly and treats "jobs skipped # because a dependency failed" as success. So we have to do some # contortions to ensure the job fails if any of its dependencies fails. diff --git a/.github/workflows/create-tag.yml b/.github/workflows/create-tag.yml index 27dcbb5741..f636991c38 100644 --- a/.github/workflows/create-tag.yml +++ b/.github/workflows/create-tag.yml @@ -4,14 +4,35 @@ on: pull_request: types: - closed - + workflow_dispatch: + inputs: + commit: + description: 'Commit hash' + required: true + type: string jobs: create-tag: - if: github.event.pull_request.merged == true && github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name && startsWith(github.event.pull_request.head.ref, 'bump-version') + if: >- + (inputs.commit || false) || + (github.event.pull_request.merged == true && + github.event.pull_request.user.login == 'github-actions' && + github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name && + startsWith(github.event.pull_request.head.ref, 'bump-version') ) runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Compute the commit + run: | + if [[ -z "${{ inputs.commit }}" ]]; then + COMMIT=$(git rev-parse ${{ github.sha }}^@ | grep -Fvx ${{ github.event.pull_request.head.sha }}) + else + COMMIT="${{ inputs.commit }}" + fi + echo "commit=$COMMIT" >> $GITHUB_ENV - name: Install rust toolchain uses: dtolnay/rust-toolchain@stable @@ -21,7 +42,8 @@ jobs: echo "version=$(cargo pkgid -p bindgen | cut -d '#' -f 2)" >> $GITHUB_ENV - name: Create tag - run: | - TAG_NAME="v${{ env.version }}" - git tag $TAG_NAME - git push origin $TAG_NAME + uses: mathieudutour/github-tag-action@v6.2 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + commit_sha: ${{ env.commit }} + custom_tag: ${{ env.version }} diff --git a/.github/workflows/deploy-book.yml b/.github/workflows/deploy-book.yml index 5eaeed5839..7b8cacc55d 100644 --- a/.github/workflows/deploy-book.yml +++ b/.github/workflows/deploy-book.yml @@ -15,7 +15,7 @@ jobs: - name: Test book run: | - curl -L https://github.com/rust-lang/mdBook/releases/download/v0.4.5/mdbook-v0.4.5-x86_64-unknown-linux-gnu.tar.gz | tar xz + curl -L https://github.com/rust-lang/mdBook/releases/download/v0.4.34/mdbook-v0.4.34-x86_64-unknown-linux-gnu.tar.gz | tar xz ./mdbook build book ./mdbook test book diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7333d62aff..d8602f9ad9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -11,7 +11,7 @@ env: jobs: cargo-publish: runs-on: ubuntu-latest - if: ${{ (github.event.workflow_run.conclusion == 'success') && (github.event.workflow.name == 'Release') }} + if: ${{ !github.event.pull_request && (github.event.workflow_run.conclusion == 'success') && (github.event.workflow.name == 'Release') }} steps: - name: Print workflow event name run: echo "${{ github.event.workflow.name }}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6d739c57d9..6620b80c98 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,10 +1,12 @@ +# This file was autogenerated by dist: https://opensource.axo.dev/cargo-dist/ +# # Copyright 2022-2024, axodotdev # SPDX-License-Identifier: MIT or Apache-2.0 # # CI that: # # * checks for a Git Tag that looks like a release -# * builds artifacts with cargo-dist (archives, installers, hashes) +# * builds artifacts with dist (archives, installers, hashes) # * uploads those artifacts to temporary workflow zip # * on success, uploads the artifacts to a GitHub Release # @@ -22,10 +24,10 @@ permissions: # must be a Cargo-style SemVer Version (must have at least major.minor.patch). # # If PACKAGE_NAME is specified, then the announcement will be for that -# package (erroring out if it doesn't have the given version or isn't cargo-dist-able). +# package (erroring out if it doesn't have the given version or isn't dist-able). # # If PACKAGE_NAME isn't specified, then the announcement will be for all -# (cargo-dist-able) packages in the workspace with that version (this mode is +# (dist-able) packages in the workspace with that version (this mode is # intended for workspaces with only one dist-able package, or with all dist-able # packages versioned/released in lockstep). # @@ -43,9 +45,9 @@ on: - '**[0-9]+.[0-9]+.[0-9]+*' jobs: - # Run 'cargo dist plan' (or host) to determine what tasks we need to do + # Run 'dist plan' (or host) to determine what tasks we need to do plan: - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} tag: ${{ !github.event.pull_request && github.ref_name || '' }} @@ -57,16 +59,16 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - - name: Install cargo-dist + - name: Install dist # we specify bash to get pipefail; it guards against the `curl` command # failing. otherwise `sh` won't catch that `curl` returned non-0 shell: bash - run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.21.0/cargo-dist-installer.sh | sh" - - name: Cache cargo-dist + run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.28.0/cargo-dist-installer.sh | sh" + - name: Cache dist uses: actions/upload-artifact@v4 with: name: cargo-dist-cache - path: ~/.cargo/bin/cargo-dist + path: ~/.cargo/bin/dist # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. @@ -74,8 +76,8 @@ jobs: # but also really annoying to build CI around when it needs secrets to work right.) - id: plan run: | - cargo dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json - echo "cargo dist ran successfully" + dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" - name: "Upload dist-manifest.json" @@ -93,18 +95,19 @@ jobs: if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null && (needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload') }} strategy: fail-fast: false - # Target platforms/runners are computed by cargo-dist in create-release. + # Target platforms/runners are computed by dist in create-release. # Each member of the matrix has the following arguments: # # - runner: the github runner - # - dist-args: cli flags to pass to cargo dist - # - install-dist: expression to run to install cargo-dist on the runner + # - dist-args: cli flags to pass to dist + # - install-dist: expression to run to install dist on the runner # # Typically there will be: # - 1 "global" task that builds universal installers # - N "local" tasks that build each platform's binaries and platform-specific installers matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }} runs-on: ${{ matrix.runner }} + container: ${{ matrix.container && matrix.container.image || null }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json @@ -115,8 +118,15 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - - name: Install cargo-dist - run: ${{ matrix.install_dist }} + - name: Install Rust non-interactively if not already installed + if: ${{ matrix.container }} + run: | + if ! command -v cargo > /dev/null 2>&1; then + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + echo "$HOME/.cargo/bin" >> $GITHUB_PATH + fi + - name: Install dist + run: ${{ matrix.install_dist.run }} # Get the dist-manifest - name: Fetch local artifacts uses: actions/download-artifact@v4 @@ -130,8 +140,8 @@ jobs: - name: Build artifacts run: | # Actually do builds and make zips and whatnot - cargo dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json - echo "cargo dist ran successfully" + dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + echo "dist ran successfully" - id: cargo-dist name: Post-build # We force bash here just because github makes it really hard to get values up @@ -141,7 +151,7 @@ jobs: run: | # Parse out what we just built and upload it to scratch storage echo "paths<> "$GITHUB_OUTPUT" - jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT" + dist print-upload-files-from-manifest --manifest dist-manifest.json >> "$GITHUB_OUTPUT" echo "EOF" >> "$GITHUB_OUTPUT" cp dist-manifest.json "$BUILD_MANIFEST_NAME" @@ -158,7 +168,7 @@ jobs: needs: - plan - build-local-artifacts - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json @@ -166,12 +176,12 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - - name: Install cached cargo-dist + - name: Install cached dist uses: actions/download-artifact@v4 with: name: cargo-dist-cache path: ~/.cargo/bin/ - - run: chmod +x ~/.cargo/bin/cargo-dist + - run: chmod +x ~/.cargo/bin/dist # Get all the local artifacts for the global tasks to use (for e.g. checksums) - name: Fetch local artifacts uses: actions/download-artifact@v4 @@ -182,8 +192,8 @@ jobs: - id: cargo-dist shell: bash run: | - cargo dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json - echo "cargo dist ran successfully" + dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage echo "paths<> "$GITHUB_OUTPUT" @@ -208,19 +218,19 @@ jobs: if: ${{ always() && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} steps: - uses: actions/checkout@v4 with: submodules: recursive - - name: Install cached cargo-dist + - name: Install cached dist uses: actions/download-artifact@v4 with: name: cargo-dist-cache path: ~/.cargo/bin/ - - run: chmod +x ~/.cargo/bin/cargo-dist + - run: chmod +x ~/.cargo/bin/dist # Fetch artifacts from scratch-storage - name: Fetch artifacts uses: actions/download-artifact@v4 @@ -231,7 +241,7 @@ jobs: - id: host shell: bash run: | - cargo dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -272,7 +282,7 @@ jobs: # still allowing individual publish jobs to skip themselves (for prereleases). # "host" however must run to completion, no skipping allowed! if: ${{ always() && needs.host.result == 'success' }} - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 308ed7675e..74ff973751 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,208 +7,220 @@ - [Removed](#removed) - [Fixed](#fixed) - [Security](#security) -- [0.70.1 (2024-08-20)](#0701-2024-08-20) +- [0.72.0 (2025-06-08)](#0720-2025-06-08) - [Added](#added-1) - [Changed](#changed-1) - [Removed](#removed-1) - [Fixed](#fixed-1) - - [Security](#security-1) -- [0.70.0 (2024-08-16)](#0700-2024-08-16) +- [v0.71.1 (2024-12-09)](#v0711-2024-12-09) + - [Fixed](#fixed-2) +- [0.71.0 (2024-12-06)](#0710-2024-12-06) - [Added](#added-2) - [Changed](#changed-2) - [Removed](#removed-2) - - [Fixed](#fixed-2) - - [Security](#security-2) -- [0.69.4 (2024-02-04)](#0694-2024-02-04) + - [Fixed](#fixed-3) +- [0.70.1 (2024-08-20)](#0701-2024-08-20) - [Added](#added-3) - [Changed](#changed-3) - [Removed](#removed-3) - - [Fixed](#fixed-3) - - [Security](#security-3) -- [0.69.3 (2024-02-04)](#0693-2024-02-04) + - [Fixed](#fixed-4) + - [Security](#security-1) +- [0.70.0 (2024-08-16)](#0700-2024-08-16) - [Added](#added-4) - [Changed](#changed-4) - [Removed](#removed-4) - - [Fixed](#fixed-4) - - [Security](#security-4) -- [0.69.2 (2024-01-13)](#0692-2024-01-13) + - [Fixed](#fixed-5) + - [Security](#security-2) +- [0.69.4 (2024-02-04)](#0694-2024-02-04) - [Added](#added-5) - [Changed](#changed-5) - [Removed](#removed-5) - - [Fixed](#fixed-5) - - [Security](#security-5) -- [0.69.1 (2023-11-02)](#0691-2023-11-02) - [Fixed](#fixed-6) -- [0.69.0 (2023-11-01)](#0690-2023-11-01) + - [Security](#security-3) +- [0.69.3 (2024-02-04)](#0693-2024-02-04) - [Added](#added-6) - [Changed](#changed-6) - [Removed](#removed-6) - [Fixed](#fixed-7) - - [Security](#security-6) -- [0.68.1](#0681) - - [Fixed](#fixed-8) -- [0.68.0](#0680) + - [Security](#security-4) +- [0.69.2 (2024-01-13)](#0692-2024-01-13) - [Added](#added-7) - [Changed](#changed-7) - [Removed](#removed-7) + - [Fixed](#fixed-8) + - [Security](#security-5) +- [0.69.1 (2023-11-02)](#0691-2023-11-02) - [Fixed](#fixed-9) -- [0.67.0](#0670) -- [0.66.1](#0661) - - [Removed](#removed-8) -- [0.66.0](#0660) +- [0.69.0 (2023-11-01)](#0690-2023-11-01) - [Added](#added-8) - [Changed](#changed-8) - - [Removed](#removed-9) -- [0.65.1](#0651) + - [Removed](#removed-8) - [Fixed](#fixed-10) -- [0.65.0](#0650) + - [Security](#security-6) +- [0.68.1](#0681) + - [Fixed](#fixed-11) +- [0.68.0](#0680) - [Added](#added-9) - [Changed](#changed-9) + - [Removed](#removed-9) + - [Fixed](#fixed-12) +- [0.67.0](#0670) +- [0.66.1](#0661) - [Removed](#removed-10) -- [0.64.0](#0640) +- [0.66.0](#0660) - [Added](#added-10) - [Changed](#changed-10) -- [0.63.0](#0630) + - [Removed](#removed-11) +- [0.65.1](#0651) + - [Fixed](#fixed-13) +- [0.65.0](#0650) - [Added](#added-11) - [Changed](#changed-11) - - [Removed](#removed-11) -- [0.62.0](#0620) + - [Removed](#removed-12) +- [0.64.0](#0640) - [Added](#added-12) - [Changed](#changed-12) - - [Fixed](#fixed-11) -- [0.61.0](#0610) +- [0.63.0](#0630) - [Added](#added-13) - [Changed](#changed-13) - - [Fixed](#fixed-12) -- [0.60.1](#0601) - - [Fixed](#fixed-13) -- [0.60.0](#0600) + - [Removed](#removed-13) +- [0.62.0](#0620) - [Added](#added-14) - - [Fixed](#fixed-14) - [Changed](#changed-14) - - [Removed](#removed-12) -- [0.59.2](#0592) -- [0.59.1](#0591) - - [Fixed](#fixed-15) -- [0.59.0](#0590) + - [Fixed](#fixed-14) +- [0.61.0](#0610) - [Added](#added-15) - - [Fixed](#fixed-16) - [Changed](#changed-15) -- [0.58.1](#0581) + - [Fixed](#fixed-15) +- [0.60.1](#0601) + - [Fixed](#fixed-16) +- [0.60.0](#0600) - [Added](#added-16) -- [0.58.0](#0580) - - [Added](#added-17) - [Fixed](#fixed-17) - [Changed](#changed-16) - - [Deprecated](#deprecated) - - [Removed](#removed-13) + - [Removed](#removed-14) +- [0.59.2](#0592) +- [0.59.1](#0591) - [Fixed](#fixed-18) - - [Security](#security-7) -- [0.57.0](#0570) - - [Added](#added-18) +- [0.59.0](#0590) + - [Added](#added-17) - [Fixed](#fixed-19) -- [0.56.0](#0560) - - [Added](#added-19) - [Changed](#changed-17) +- [0.58.1](#0581) + - [Added](#added-18) +- [0.58.0](#0580) + - [Added](#added-19) - [Fixed](#fixed-20) -- [0.55.1](#0551) + - [Changed](#changed-18) + - [Deprecated](#deprecated) + - [Removed](#removed-15) - [Fixed](#fixed-21) -- [0.55.0](#0550) - - [Removed](#removed-14) + - [Security](#security-7) +- [0.57.0](#0570) - [Added](#added-20) - - [Changed](#changed-18) - [Fixed](#fixed-22) -- [0.54.1](#0541) +- [0.56.0](#0560) - [Added](#added-21) - [Changed](#changed-19) - [Fixed](#fixed-23) -- [0.54.0](#0540) +- [0.55.1](#0551) + - [Fixed](#fixed-24) +- [0.55.0](#0550) + - [Removed](#removed-16) - [Added](#added-22) - [Changed](#changed-20) - - [Fixed](#fixed-24) -- [0.53.3](#0533) - - [Added](#added-23) - [Fixed](#fixed-25) -- [0.53.2](#0532) +- [0.54.1](#0541) + - [Added](#added-23) - [Changed](#changed-21) -- [0.53.1](#0531) + - [Fixed](#fixed-26) +- [0.54.0](#0540) - [Added](#added-24) -- [0.53.0](#0530) - - [Added](#added-25) - [Changed](#changed-22) - - [Fixed](#fixed-26) -- [0.52.0](#0520) - - [Added](#added-26) - - [Changed](#changed-23) - [Fixed](#fixed-27) -- [0.51.1](#0511) +- [0.53.3](#0533) + - [Added](#added-25) - [Fixed](#fixed-28) +- [0.53.2](#0532) + - [Changed](#changed-23) +- [0.53.1](#0531) + - [Added](#added-26) +- [0.53.0](#0530) + - [Added](#added-27) - [Changed](#changed-24) -- [0.51.0](#0510) - [Fixed](#fixed-29) +- [0.52.0](#0520) + - [Added](#added-28) - [Changed](#changed-25) - - [Added](#added-27) + - [Fixed](#fixed-30) +- [0.51.1](#0511) + - [Fixed](#fixed-31) + - [Changed](#changed-26) +- [0.51.0](#0510) + - [Fixed](#fixed-32) + - [Changed](#changed-27) + - [Added](#added-29) - [0.50.0](#0500) - - [Added](#added-28) + - [Added](#added-30) - [0.49.3](#0493) - - [Added](#added-29) + - [Added](#added-31) - [0.49.2](#0492) - - [Changed](#changed-26) + - [Changed](#changed-28) - [0.49.1](#0491) - - [Fixed](#fixed-30) - - [Changed](#changed-27) + - [Fixed](#fixed-33) + - [Changed](#changed-29) - [0.49.0](#0490) - - [Added](#added-30) - - [Fixed](#fixed-31) - - [Changed](#changed-28) + - [Added](#added-32) + - [Fixed](#fixed-34) + - [Changed](#changed-30) - [0.48.1](#0481) - - [Fixed](#fixed-32) + - [Fixed](#fixed-35) - [0.48.0](#0480) - - [Changed](#changed-29) - - [Fixed](#fixed-33) + - [Changed](#changed-31) + - [Fixed](#fixed-36) - [0.47.4](#0474) - - [Added](#added-31) + - [Added](#added-33) - [0.47.3](#0473) - - [Changed](#changed-30) + - [Changed](#changed-32) - [0.47.2](#0472) - - [Fixed](#fixed-34) + - [Fixed](#fixed-37) - [0.47.1](#0471) - - [Changed](#changed-31) - - [Fixed](#fixed-35) + - [Changed](#changed-33) + - [Fixed](#fixed-38) - [0.47.0](#0470) - - [Changed](#changed-32) - - [Fixed](#fixed-36) + - [Changed](#changed-34) + - [Fixed](#fixed-39) - [0.33.1 .. 0.46.0](#0331--0460) - - [Added](#added-32) - - [Removed](#removed-15) - - [Changed](#changed-33) - - [Fixed](#fixed-37) + - [Added](#added-34) + - [Removed](#removed-17) + - [Changed](#changed-35) + - [Fixed](#fixed-40) - [0.33.1](#0331) - - [Fixed](#fixed-38) + - [Fixed](#fixed-41) - [0.33.0](#0330) - [0.32.2](#0322) - - [Fixed](#fixed-39) + - [Fixed](#fixed-42) - [0.32.1](#0321) - - [Fixed](#fixed-40) + - [Fixed](#fixed-43) - [0.32.0](#0320) - - [Added](#added-33) - - [Changed](#changed-34) - - [Fixed](#fixed-41) + - [Added](#added-35) + - [Changed](#changed-36) + - [Fixed](#fixed-44) - [0.31.0](#0310) - - [Added](#added-34) - - [Changed](#changed-35) + - [Added](#added-36) + - [Changed](#changed-37) - [Deprecated](#deprecated-1) - - [Removed](#removed-16) - - [Fixed](#fixed-42) + - [Removed](#removed-18) + - [Fixed](#fixed-45) - [0.30.0](#0300) - - [Added](#added-35) - - [Changed](#changed-36) + - [Added](#added-37) + - [Changed](#changed-38) - [Deprecated](#deprecated-2) - - [Fixed](#fixed-43) + - [Fixed](#fixed-46) - [0.29.0](#0290) - - [Added](#added-36) - - [Changed](#changed-37) - - [Fixed](#fixed-44) + - [Added](#added-38) + - [Changed](#changed-39) + - [Fixed](#fixed-47) @@ -217,9 +229,73 @@ ## Added ## Changed ## Removed +- Removed support for generating code for rustc versions < 1.51. ## Fixed +- Typo in code for `--rustified-non-exhaustive-enums` (#3266) ## Security +# 0.72.0 (2025-06-08) + +## Added + + * Report enums in ParseCallbacks. + * Refactor item_name method to use ItemInfo struct. + * Add callback to modify contents of macro + * Discovery callbacks for functions and methods. + * Options to generate uncallable C++ functions. + * Provide option to get real virtual fn receiver. + +## Changed + + * Generate bindings compatible with current rustc version by default. + +## Removed + + * Remove unused which-rustfmt feature + * Remove warning for opaque forward declarations + +## Fixed + + * More sophisticated handling of the triple in rust_to_clang_target + * Rename *-apple-ios-sim to ...simulator + * Fix OpenCL vectors that use "ext_vector_type". + * Fix union layout when it contains 0 sized array. + * Avoid crashing on variadic unions without layout information. + * Distinguish char16_t. + * Fix bugs in --clang-macro-fallback + * Add missed unsafe in the raw_set_bit function + * Use link_name for dynamic library loading + * Add "gen" to list of rust keywords in 'rust_mangle' + * Use appropriate `rustfmt --format ...` param + +# v0.71.1 (2024-12-09) +## Fixed +- Fix `--version` and `--generate-shell-completions` (#3040) + +# 0.71.0 (2024-12-06) +## Added +- Add the `ParseCallbacks::new_item_found` callback to expose the original and final name of structs, unions and enums (#2658). +- Add the `field_type_name` field to `FieldInfo` to expose the name of the type of a field (#2863) +- Add support for custom attributes with the `--with-attribute-custom` flag (#2866) +- Allow setting `--rust-target` to any Rust version supported by bindgen (#2993) +- Use c-string literals if the `--generate-cstr` flag is used for Rust targets after 1.77 under the 2021 edition (#2996) +- Add the `--rust-edition` flag which allows to select which Rust edition to target. (#3002, #3013) +- Use `unsafe extern` instead of `extern` in blocks for any Rust target after 1.82. (#3015) +## Changed +- The `--wrap-static-fns` related options no longer require the experimental feature or flag (#2928) +- Use the `Display` implementation instead of the `Debug` one for `BindgenError` in `bindgen-cli` (#3005) +## Removed +- Dropped support for any Clang versions strictly lower than 9.0 (#2932) +- Dropped support for any Rust version strictly lower than 1.33 (#2993) +## Fixed +- Represent opaque types in a FFI-safe way (#2880) +- Use the underlying type of any atomic type instead of panicking (#2920) +- Use the right characters for newlines on windows (#2923) +- Inlined namespaces are properly recognized now (#2950) +- Unsafe calls to `libloading` are now wrapped in `unsafe` blocks when using dynamic loading (#2961) +- The `ParseCallbacks::field_visibility` callback is now called for newtypes as well (#2967) +- Gate the use of the `addr_of` and `addr_of_mut` macros under the 1.51 rust version (#2988) + # 0.70.1 (2024-08-20) ## Added ## Changed @@ -235,7 +311,7 @@ - Add option to use DST structs for flexible arrays (--flexarray-dst, #2772). - Add option to dynamically load variables (#2812). - Add option in CLI to use rustified non-exhaustive enums (--rustified-non-exhaustive-enum, #2847). -- Add support for custom attributes (--with-attribute-custom, #2866) +- Add field_type_name to FieldInfo. ## Changed - Remove which and lazy-static dependencies (#2809, #2817). - Generate compile-time layout tests (#2787). @@ -369,7 +445,7 @@ This version was skipped due to some problems on the release workflow. * The `--wrap-static-fns` option can now wrap `va_list` functions as variadic functions with the experimental `ParseCallbacks::wrap_as_variadic_fn` method. * Add target mappings for riscv32imc and riscv32imac. -* Add the `ParseCallbacks::field_visibility` method to modify field visibility. +* Add the `ParseCallbacks::field_visibility` method to modify field visibility. ## Changed @@ -393,7 +469,7 @@ This version was skipped due to some problems on the release workflow. * Compute visibility of bitfield unit based on actual field visibility: A bitfield unit field and its related functions now have their visibility determined based on the most private between the default visibility and the - actual visibility of the bitfields within the unit. + actual visibility of the bitfields within the unit. ## Removed * Remove redundant Cargo features, which were all implicit: @@ -449,7 +525,7 @@ This version was skipped due to some problems on the release workflow. types. (#2463) * The `Builder::rustfmt_bindings` methods and the `--no-rustfmt-bindings` flag are now deprecated in favor of the formatter API. (#2453) - + ## Removed * The following deprecated flags were removed: `--use-msvc-mangling`, `--rustfmt-bindings` and `--size_t-is-usize`. (#2408) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ff48cf1df7..9c28e198c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -54,18 +54,18 @@ We abide by the [Rust Code of Conduct][coc] and ask that you do as well. Think you've found a bug? File an issue! To help us understand and reproduce the issue, provide us with: -* A (preferably reduced) C/C++ header file that reproduces the issue -* The `bindgen` flags used to reproduce the issue with the header file -* The expected `bindgen` output -* The actual `bindgen` output -* The [debugging logs](#debug-logging) generated when running `bindgen` on this testcase +- A (preferably reduced) C/C++ header file that reproduces the issue +- The `bindgen` flags used to reproduce the issue with the header file +- The expected `bindgen` output +- The actual `bindgen` output +- The [debugging logs](#debug-logging) generated when running `bindgen` on this testcase ## Looking to Start Contributing to `bindgen`? -* [Issues labeled "easy"](https://github.com/rust-lang/rust-bindgen/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy) -* [Issues labeled "less easy"](https://github.com/rust-lang/rust-bindgen/issues?q=is%3Aopen+is%3Aissue+label%3AE-less-easy) -* [Issues labeled "help wanted"](https://github.com/rust-lang/rust-bindgen/labels/help%20wanted) -* Still can't find something to work on? [Drop a comment here](https://github.com/rust-lang/rust-bindgen/issues/747) +- [Issues labeled "easy"](https://github.com/rust-lang/rust-bindgen/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy) +- [Issues labeled "less easy"](https://github.com/rust-lang/rust-bindgen/issues?q=is%3Aopen+is%3Aissue+label%3AE-less-easy) +- [Issues labeled "help wanted"](https://github.com/rust-lang/rust-bindgen/labels/help%20wanted) +- Still can't find something to work on? [Drop a comment here](https://github.com/rust-lang/rust-bindgen/issues/747) ## Prerequisites @@ -82,16 +82,16 @@ To check via command line, you can run `cargo +nightly fmt --check`. To build the `bindgen` library and the `bindgen` executable: -``` -$ cargo build +```sh +cargo build ``` If you installed multiple versions of llvm, it may not be able to locate the -latest version of libclang. In that case, you may want to either uninstall other -versions of llvm, or specify the path of the desired libclang explicitly: +latest version of `libclang`. In that case, you may want to either uninstall other +versions of llvm, or specify the path of the desired `libclang` explicitly: -``` -$ export LIBCLANG_PATH=path/to/clang-9.0/lib +```sh +export LIBCLANG_PATH=path/to/clang-9.0/lib ``` ## Testing @@ -107,7 +107,7 @@ There are also some integration tests in the `./bindgen-integration` crate, whic generate bindings to some C++ code, and then uses the bindings, asserting that values are what we expect them to be, both on the Rust and C++ side. -The generated and expected bindings are formatted with [prettyplease] before they are +The generated and expected bindings are formatted with [`prettyplease`] before they are compared. It is a default (but optional) dependency of `bindgen`, so be sure to keep that in mind (if you built `bindgen` with the `--no-default-features` option of Cargo). @@ -118,14 +118,13 @@ Note: running `cargo test` from the root directory of `bindgen`'s repository doe automatically test the generated bindings or run the integration tests. These steps must be performed manually when needed. - ### Testing Bindings Generation To regenerate bindings from the corpus of test headers in `bindgen-tests/tests/headers` and compare them against the expected bindings in `bindgen-tests/tests/expectations/tests`, run: -``` -$ cargo test +```sh +cargo test ``` As long as you aren't making any changes to `bindgen`'s output, running this @@ -134,12 +133,12 @@ should be sufficient to test your local modifications. You may set the `BINDGEN_OVERWRITE_EXPECTED` environment variable to overwrite the expected bindings with `bindgen`'s current output: -``` -$ BINDGEN_OVERWRITE_EXPECTED=1 cargo test +```sh +BINDGEN_OVERWRITE_EXPECTED=1 cargo test ``` -If you set the BINDGEN_TESTS_DIFFTOOL environment variable, `cargo test` will -execute $BINDGEN_TESTS_DIFFTOOL /path/of/expected/output /path/of/actual/output +If you set the `BINDGEN_TESTS_DIFFTOOL` environment variable, `cargo test` will +execute `BINDGEN_TESTS_DIFFTOOL /path/of/expected/output /path/of/actual/output` when the expected output differs from the actual output. You can use this to hand check differences by setting it to e.g. "meld" (assuming you have meld installed). @@ -157,14 +156,14 @@ pass. Also, run the integration tests (see below). You can do this with these commands: -``` -$ cd bindgen-tests/tests/expectations -$ cargo test +```sh +cd bindgen-tests/tests/expectations +cargo test ``` ### Testing a Single Header's Bindings Generation and Compiling its Bindings -Note: You will need to install [Graphviz](https://graphviz.org/) since that +Note: You will need to install [graphviz](https://graphviz.org/) since that is a dependency for running `test-one.sh`. Sometimes it's useful to work with one test header from start (generating @@ -173,8 +172,8 @@ tests). This can be done with the `bindgen-tests/tests/test-one.sh` script. It s searching for test headers. For example, to test `tests/headers/what_is_going_on.hpp`, execute this command: -``` -$ ./bindgen-tests/tests/test-one.sh going +```sh +./bindgen-tests/tests/test-one.sh going ``` Note that `test-one.sh` does not recompile `bindgen`, so if you change the code, @@ -197,9 +196,9 @@ specify them at the top of the test header, with a comment like this: Then verify the new Rust bindings compile and pass their layout tests: -``` -$ cd bindgen-tests/tests/expectations -$ cargo test new_test_header +```sh +cd bindgen-tests/tests/expectations +cargo test new_test_header ``` ### Test Expectations and `libclang` Versions @@ -210,8 +209,8 @@ can add multiple test expectations, one for each supported `libclang` version. Instead of having a single `bindgen-tests/tests/expectations/tests/my_test.rs` file, add each of: -* `bindgen-tests/tests/expectations/tests/libclang-16/my_test.rs` -* `bindgen-tests/tests/expectations/tests/libclang-9/my_test.rs` +- `bindgen-tests/tests/expectations/tests/libclang-16/my_test.rs` +- `bindgen-tests/tests/expectations/tests/libclang-9/my_test.rs` If you need to update the test expectations for a test file that generates different bindings for different `libclang` versions, you *don't* need to have @@ -224,8 +223,8 @@ Usually, `bindgen`'s test runner can infer which version of `libclang` you have. If for some reason it can't, you can force a specific `libclang` version to check the bindings against with a cargo feature: -``` -$ cargo test --features __testing_only_libclang_$VERSION +```sh +cargo test --features __testing_only_libclang_$VERSION ``` depending on which version of `libclang` you have installed. @@ -238,9 +237,9 @@ values are what we expect them to be, both on the Rust and C++ side. To run the integration tests, issue the following: -``` -$ cd bindgen-integration -$ cargo test +```sh +cd bindgen-integration +cargo test ``` ### Fuzzing `bindgen` with `csmith` @@ -257,7 +256,7 @@ The `tests/quickchecking` crate generates property tests for `bindgen`. From the crate's directory you can run the tests with `cargo run`. For details on additional configuration including how to preserve / inspect the generated property tests, see -[./tests/quickchecking/README.md](./tests/quickchecking/README.md). +[`./tests/quickchecking/README.md`](./tests/quickchecking/README.md). ## Code Overview @@ -274,39 +273,39 @@ The umbrella IR type is the `Item`. It contains various nested `enum`s that let us drill down and get more specific about the kind of construct that we're looking at. Here is a summary of the IR types and their relationships: -* `Item` contains: - * An `ItemId` to uniquely identify it. - * An `ItemKind`, which is one of: - * A `Module`, which is originally a C++ namespace and becomes a Rust +- `Item` contains: + - An `ItemId` to uniquely identify it. + - An `ItemKind`, which is one of: + - A `Module`, which is originally a C++ namespace and becomes a Rust module. It contains the set of `ItemId`s of `Item`s that are defined within it. - * A `Type`, which contains: - * A `Layout`, describing the type's size and alignment. - * A `TypeKind`, which is one of: - * Some integer type. - * Some float type. - * A `Pointer` to another type. - * A function pointer type, with `ItemId`s of its parameter types + - A `Type`, which contains: + - A `Layout`, describing the type's size and alignment. + - A `TypeKind`, which is one of: + - Some integer type. + - Some float type. + - A `Pointer` to another type. + - A function pointer type, with `ItemId`s of its parameter types and return type. - * An `Alias` to another type (`typedef` or `using X = ...`). - * A fixed size `Array` of `n` elements of another type. - * A `Comp` compound type, which is either a `struct`, `class`, + - An `Alias` to another type (`typedef` or `using X = ...`). + - A fixed size `Array` of `n` elements of another type. + - A `Comp` compound type, which is either a `struct`, `class`, or `union`. This is potentially a template definition. - * A `TemplateInstantiation` referencing some template definition + - A `TemplateInstantiation` referencing some template definition and a set of template argument types. - * Etc... - * A `Function`, which contains: - * An ABI - * A mangled name - * a `FunctionKind`, which describes whether this function is a plain + - Etc... + - A `Function`, which contains: + - An ABI + - A mangled name + - a `FunctionKind`, which describes whether this function is a plain function, method, static method, constructor, destructor, etc. - * The `ItemId` of its function pointer type. - * A `Var` representing a static variable or `#define` constant, which + - The `ItemId` of its function pointer type. + - A `Var` representing a static variable or `#define` constant, which contains: - * Its type's `ItemId` - * Optionally, a mangled name - * Optionally, a value - * An optional `clang::SourceLocation` that holds the first source code + - Its type's `ItemId` + - Optionally, a mangled name + - Optionally, a value + - An optional `clang::SourceLocation` that holds the first source code location where the `Item` was encountered. The IR forms a graph of interconnected and inter-referencing types and @@ -323,8 +322,8 @@ parameters a given type uses. The analyses are defined in `ir::analysis::MonotoneFramework` trait. The final phase is generating Rust source text from the analyzed IR, and it is -defined in `src/codegen/*`. We use the `quote` crate, which provides the `quote! -{ ... }` macro for quasi-quoting Rust forms. Some options that affect the +defined in `src/codegen/*`. We use the `quote` crate, which provides the `quote!{ ... }` +macro for quasi-quoting Rust forms. Some options that affect the generated Rust code are implemented using the [`syn`](https://docs.rs/syn) crate. ### Implementing new options using `syn` @@ -351,13 +350,13 @@ changes should be squashed into the original commit. Unsure who to ask for review? Ask any of: -* `@emilio` -* `@pvdrz` +- `@emilio` +- `@pvdrz` More resources: -* [Servo's GitHub Workflow](https://github.com/servo/servo/wiki/Github-workflow) -* [Beginner's Guide to Rebasing and Squashing](https://github.com/servo/servo/wiki/Beginner's-guide-to-rebasing-and-squashing) +- [Servo's GitHub Workflow](https://github.com/servo/servo/wiki/Github-workflow) +- [Beginner's Guide to Rebasing and Squashing](https://github.com/servo/servo/wiki/Beginner's-guide-to-rebasing-and-squashing) ## Generating Graphviz Dot Files @@ -368,22 +367,22 @@ debugging bindgen! First, make sure you have Graphviz and `dot` installed: -``` -$ brew install graphviz # OS X -$ sudo dnf install graphviz # Fedora -$ # Etc... +```sh +brew install graphviz # OS X +sudo dnf install graphviz # Fedora +# Etc... ``` Then, use the `--emit-ir-graphviz` flag to generate a `dot` file from our IR: -``` -$ cargo run -- example.hpp --emit-ir-graphviz output.dot +```sh +cargo run -- example.hpp --emit-ir-graphviz output.dot ``` Finally, convert the `dot` file to an image: -``` -$ dot -Tpng output.dot -o output.png +```sh +dot -Tpng output.dot -o output.png ``` The final result will look something like this: @@ -395,14 +394,14 @@ The final result will look something like this: To help debug what `bindgen` is doing, you can define the environment variable `RUST_LOG=bindgen` to get a bunch of debugging log spew. -``` -$ RUST_LOG=bindgen ./target/debug/bindgen [flags...] ~/path/to/some/header.h +```sh +RUST_LOG=bindgen ./target/debug/bindgen [flags...] ~/path/to/some/header.h ``` This logging can also be used when debugging failing tests: -``` -$ RUST_LOG=bindgen cargo test +```sh +RUST_LOG=bindgen cargo test ``` ## Using `creduce` to Minimize Test Cases @@ -419,10 +418,10 @@ that same bad behavior. Often, you can install `creduce` from your OS's package manager: -``` -$ sudo apt install creduce -$ brew install creduce -$ # Etc... +```sh +sudo apt install creduce +brew install creduce +# Etc... ``` Otherwise, follow [these instructions](https://github.com/csmith-project/creduce/blob/master/INSTALL.md) for building and/or installing `creduce`. @@ -436,7 +435,9 @@ Running `creduce` requires two things: With those two things in hand, running `creduce` looks like this: - $ creduce ./predicate.sh ./isolated-test-case.h +```sh +creduce ./predicate.sh ./isolated-test-case.h +``` ### Isolating Your Test Case @@ -511,8 +512,8 @@ path/to/rust-bindgen/csmith-fuzzing/predicate.py \ For details on all the flags that you can pass to `predicate.py`, run: -``` -$ path/to/rust-bindgen/csmith-fuzzing/predicate.py --help +```sh +path/to/rust-bindgen/csmith-fuzzing/predicate.py --help ``` And you can always write your own, arbitrary predicate script if you prefer. @@ -535,9 +536,9 @@ To cut a release, the following needs to happen: Update the CHANGELOG.md file with the changes from the last release. Something like the following is a useful way to check what has landed: - ``` - $ git log --oneline v0.62.0..HEAD - ``` +```sh +git log --oneline v0.62.0..HEAD +``` Also worth checking the [next-release tag](https://github.com/rust-lang/rust-bindgen/pulls?q=is%3Apr+label%3Anext-release). @@ -554,12 +555,14 @@ important fix) you can skip this. ### Tag and publish Once you're in `main`. Remember to install `doctoc` by running: -``` + +```sh npm install doctoc ``` And then run: -``` + +```sh cargo release [patch|minor] --no-publish --execute ``` @@ -573,8 +576,8 @@ This does the following: The `patch` and `minor` refer to semver concepts: -- `patch` would bump __v0.68.1__ to __v0.68.2__ -- `minor` would bump __v0.68.2__ to __v0.69.0__ +- `patch` would bump **v0.68.1** to **v0.68.2** +- `minor` would bump **v0.68.2** to **v0.69.0** > NOTE: > We use the `--no-publish` so that the crates are only published after the release is complete. @@ -595,12 +598,12 @@ to avoid notifying watchers of the repo should a CI step fail. If everything succeeds, tarballs containing bindgen cli executables for Linux and MacOS (both for x86 and Arm) will be created. -See `[workspace.metadata.dist]` section in Cargo.toml for the configuration. +See `[workspace.metadata.dist]` section in `Cargo.toml` for the configuration. To update the release configuration, -when a new cargo-dist is available: +when a new `cargo-dist` is available: -``` +```sh cargo dist init # from "cargo install cargo-dist" ``` @@ -620,4 +623,4 @@ and run a new workflow using the "Run Workflow" button. Remember that crates.io releases cannot be deleted! -[prettyplease]: https://github.com/dtolnay/prettyplease +[`prettyplease`]: https://github.com/dtolnay/prettyplease diff --git a/Cargo.lock b/Cargo.lock index 4786857205..28bc2732ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,37 +4,83 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "annotate-snippets" -version = "0.11.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e35ed54e5ea7997c14ed4c70ba043478db1112e98263b3b035907aa197d991" +checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4" dependencies = [ "anstyle", "unicode-width", ] +[[package]] +name = "anstream" +version = "0.6.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", +] [[package]] name = "bindgen" -version = "0.70.1" +version = "0.72.0" dependencies = [ "annotate-snippets", - "bitflags 2.2.1", + "bitflags", "cexpr", "clang-sys", + "clap", + "clap_complete", "itertools", "log", "prettyplease", @@ -43,17 +89,15 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.18", + "syn", ] [[package]] name = "bindgen-cli" -version = "0.70.1" +version = "0.72.0" dependencies = [ "bindgen", - "clap", - "clap_complete", - "env_logger 0.10.0", + "env_logger 0.10.2", "log", "proc-macro2", "shlex", @@ -72,28 +116,21 @@ name = "bindgen-tests" version = "0.1.0" dependencies = [ "bindgen", - "clap", - "clap_complete", "owo-colors", "prettyplease", "proc-macro2", + "regex", "shlex", "similar", - "syn 2.0.18", + "syn", "tempfile", ] [[package]] name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.2.1" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "block" @@ -103,9 +140,12 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "cc" -version = "1.0.78" +version = "1.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" +dependencies = [ + "shlex", +] [[package]] name = "cexpr" @@ -118,15 +158,15 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "clang-sys" -version = "1.4.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -135,55 +175,64 @@ dependencies = [ [[package]] name = "clap" -version = "4.1.4" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ - "bitflags 1.3.2", + "clap_builder", "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +dependencies = [ + "anstream", + "anstyle", "clap_lex", - "is-terminal", - "once_cell", "strsim", - "termcolor", ] [[package]] name = "clap_complete" -version = "4.2.0" +version = "4.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c22dcfb410883764b29953103d9ef7bb8fe21b3fa1158bc99986c2067294bd" +checksum = "abb745187d7f4d76267b37485a65e0149edd0e91a4cfcdd3f27524ad86cee9f3" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.1.0" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.107", + "syn", ] [[package]] name = "clap_lex" -version = "0.3.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" -dependencies = [ - "os_str_bytes", -] +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "either" -version = "1.8.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "env_logger" @@ -197,9 +246,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -210,139 +259,120 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.1" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ - "errno-dragonfly", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] -name = "errno-dragonfly" -version = "0.1.2" +name = "fastrand" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] -name = "fastrand" -version = "1.8.0" +name = "getrandom" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ - "instant", + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", - "wasi", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "humantime" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" [[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.4" +name = "is-terminal" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ + "hermit-abi", "libc", - "windows-sys 0.42.0", + "windows-sys", ] [[package]] -name = "is-terminal" -version = "0.4.7" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi", - "io-lifetimes", - "rustix", - "windows-sys 0.48.0", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] [[package]] name = "libc" -version = "0.2.154" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "winapi", + "windows-targets", ] [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "log" -version = "0.4.17" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "malloc_buf" @@ -355,9 +385,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "minimal-lexical" @@ -386,61 +416,37 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "os_str_bytes" -version = "6.4.1" +name = "once_cell_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] name = "owo-colors" -version = "3.5.0" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e" [[package]] name = "prettyplease" -version = "0.2.7" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ded2b5b204571f065ab8540367d738dfe1b3606ab9eb669dcfb5e7a3a07501" +checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" dependencies = [ "proc-macro2", - "syn 2.0.18", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.107", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", + "syn", ] [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -467,13 +473,19 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.28" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "rand" version = "0.8.5" @@ -489,23 +501,26 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.16", ] [[package]] -name = "redox_syscall" -version = "0.3.5" +name = "regex" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ - "bitflags 1.3.2", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", ] [[package]] -name = "regex" -version = "1.7.1" +name = "regex-automata" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -514,28 +529,27 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" -version = "0.37.7" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "bitflags 1.3.2", + "bitflags", "errno", - "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -546,9 +560,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "similar" -version = "2.2.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" [[package]] name = "strsim" @@ -558,20 +572,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.107" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.18" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -580,22 +583,22 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.5.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ - "cfg-if", "fastrand", - "redox_syscall", + "getrandom 0.3.3", + "once_cell", "rustix", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -611,202 +614,124 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" [[package]] -name = "version_check" -version = "0.9.4" +name = "utf8parse" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "winapi" -version = "0.3.9" +name = "wasi" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "wit-bindgen-rt", ] -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-targets 0.42.2", + "windows-sys", ] [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.48.1", + "windows-targets", ] [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.48.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" -dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "windows_i686_gnu" -version = "0.48.0" +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" +name = "wit-bindgen-rt" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] diff --git a/Cargo.toml b/Cargo.toml index 400fd8788a..edb0d35371 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +resolver = "2" members = [ "bindgen", "bindgen-cli", @@ -7,31 +8,82 @@ members = [ "bindgen-tests/tests/quickchecking", "bindgen-tests/tests/expectations", ] - default-members = [ "bindgen", "bindgen-cli", "bindgen-tests", ] -# Config for 'cargo dist' -[workspace.metadata.dist] -# The preferred cargo-dist version to use in CI (Cargo.toml SemVer syntax) -cargo-dist-version = "0.21.0" -# CI backends to support -ci = "github" -# The installers to generate for each app -installers = ["shell", "powershell"] -# Target platforms to build apps for (Rust target-triple syntax) -targets = ["aarch64-apple-darwin", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"] -# Whether to consider the binaries in a package for distribution (defaults true) -dist = false -# Which actions to run on pull requests -pr-run-mode = "plan" -# Whether to install an updater program -install-updater = false -# Path that installers should place binaries in -install-path = "CARGO_HOME" +[workspace.package] +# If you change this, also update README.md +rust-version = "1.70.0" +edition = "2021" + +# All dependency version management is centralized here +[workspace.dependencies] +annotate-snippets = "0.11.4" +bindgen = { version = "0.72.0", path = "./bindgen", default-features = false } +bitflags = "2.2.1" +block = "0.1" +cc = "1.0" +cexpr = "0.6" +clang-sys = "1" +clap = "4" +clap_complete = "4" +env_logger = "0.10.0" +itertools = { version = ">=0.10,<0.15", default-features = false } +libloading = "0.8" +log = "0.4" +objc = "0.2" +owo-colors = "4.1.0" +prettyplease = "0.2.7" +proc-macro2 = "1.0.80" +quickcheck = "1.0" +quote = { version = "1", default-features = false } +regex = { version = "1.5.3", default-features = false } +rustc-hash = "2.1.0" +shlex = "1" +similar = "2.2.1" +syn = "2.0" +tempfile = "3" + +[workspace.lints.rust] +unused_qualifications = "warn" + +[workspace.lints.clippy] +pedantic = { level = "warn", priority = -1 } + +cast_possible_truncation = "allow" +cast_possible_wrap = "allow" +cast_precision_loss = "allow" +cast_sign_loss = "allow" +default_trait_access = "allow" +ignored_unit_patterns = "allow" +implicit_hasher = "allow" +items_after_statements = "allow" +match_same_arms = "allow" +maybe_infinite_iter = "allow" +missing_errors_doc = "allow" +missing_panics_doc = "allow" +module_name_repetitions = "allow" +must_use_candidate = "allow" +redundant_closure_for_method_calls = "allow" +return_self_not_must_use = "allow" +similar_names = "allow" +struct_excessive_bools = "allow" +struct_field_names = "allow" +unnecessary_wraps = "allow" +unreadable_literal = "allow" +used_underscore_binding = "allow" +wildcard_imports = "allow" + +# TODO +trivially_copy_pass_by_ref = "allow" +unused_self = "allow" + +# Theese seem to be ok to ignore for now +enum_glob_use = "allow" +too_many_lines = "allow" # Config for 'cargo release' [workspace.metadata.release] diff --git a/bindgen-cli/Cargo.toml b/bindgen-cli/Cargo.toml index d75867b76b..e5d49a6ecc 100644 --- a/bindgen-cli/Cargo.toml +++ b/bindgen-cli/Cargo.toml @@ -1,6 +1,8 @@ +lints.workspace = true + [package] authors = [ - "The rust-bindgen project contributors", + "The rust-bindgen project contributors", ] description = "Automatically generates Rust FFI bindings to C and C++ libraries." keywords = ["bindings", "ffi", "code-generation"] @@ -11,22 +13,20 @@ readme = "../README.md" repository = "https://github.com/rust-lang/rust-bindgen" documentation = "https://docs.rs/bindgen" homepage = "https://rust-lang.github.io/rust-bindgen/" -version = "0.70.1" -edition = "2018" -rust-version = "1.70.0" +version = "0.72.0" +rust-version.workspace = true +edition.workspace = true [[bin]] path = "main.rs" name = "bindgen" [dependencies] -bindgen = { path = "../bindgen", version = "=0.70.1", default-features = false, features = ["__cli", "experimental", "prettyplease"] } -clap = { version = "4", features = ["derive"] } -clap_complete = "4" -env_logger = { version = "0.10.0", optional = true } -log = { version = "0.4", optional = true } -proc-macro2 = { version = "1", default-features = false } -shlex = "1" +bindgen = { workspace = true, features = ["__cli", "experimental", "prettyplease"] } +env_logger = { workspace = true, optional = true } +log = { workspace = true, optional = true } +proc-macro2.workspace = true +shlex.workspace = true [features] default = ["logging", "runtime"] diff --git a/bindgen-cli/main.rs b/bindgen-cli/main.rs index caa47c6268..2d8d370ef1 100644 --- a/bindgen-cli/main.rs +++ b/bindgen-cli/main.rs @@ -1,7 +1,6 @@ use std::env; -mod options; -use crate::options::builder_from_flags; +use bindgen::builder_from_flags; #[cfg(feature = "logging")] fn clang_version_check() { @@ -36,20 +35,25 @@ pub fn main() { std::panic::set_hook(Box::new(move |info| { if verbose { - print_verbose_err() + print_verbose_err(); } - eprintln!("{}", info); + eprintln!("{info}"); })); - let bindings = - builder.generate().expect("Unable to generate bindings"); + let bindings = match builder.generate() { + Ok(bindings) => bindings, + Err(err) => { + eprintln!("Unable to generate bindings: {err}"); + std::process::exit(1) + } + }; let _ = std::panic::take_hook(); bindings.write(output).expect("Unable to write output"); } Err(error) => { - eprintln!("{}", error); + eprintln!("{error}"); std::process::exit(1); } }; diff --git a/bindgen-integration/Cargo.toml b/bindgen-integration/Cargo.toml index ccdd1467df..5c8c89d528 100644 --- a/bindgen-integration/Cargo.toml +++ b/bindgen-integration/Cargo.toml @@ -1,3 +1,5 @@ +lints.workspace = true + [package] name = "bindgen-integration" description = "A package to test various bindgen features" @@ -5,10 +7,12 @@ version = "0.1.0" authors = ["Emilio Cobos Álvarez "] publish = false build = "build.rs" +rust-version.workspace = true +edition.workspace = true [build-dependencies] -bindgen = { path = "../bindgen", features = ["experimental"] } -cc = "1.0" +bindgen = { workspace = true, default-features = true, features = ["experimental"] } +cc.workspace = true [features] static = ["bindgen/static"] diff --git a/bindgen-integration/build.rs b/bindgen-integration/build.rs index 88ba945366..1b7c2b3b82 100644 --- a/bindgen-integration/build.rs +++ b/bindgen-integration/build.rs @@ -1,7 +1,8 @@ extern crate bindgen; use bindgen::callbacks::{ - DeriveInfo, IntKind, MacroParsingBehavior, ParseCallbacks, + DeriveInfo, IntKind, ItemInfo, MacroParsingBehavior, ParseCallbacks, Token, + TokenKind, }; use bindgen::{Builder, EnumVariation, Formatter}; use std::collections::HashSet; @@ -98,21 +99,23 @@ impl ParseCallbacks for MacroCallback { _ => { // The system might provide lots of functional macros. // Ensure we did not miss handling one that we meant to handle. - assert!(!name.starts_with("TESTMACRO_"), "name = {}", name); + assert!(!name.starts_with("TESTMACRO_"), "name = {name}"); } } } - fn item_name(&self, original_item_name: &str) -> Option { - if original_item_name.starts_with("my_prefixed_") { + fn item_name(&self, item_info: ItemInfo) -> Option { + if item_info.name.starts_with("my_prefixed_") { Some( - original_item_name + item_info + .name .trim_start_matches("my_prefixed_") .to_string(), ) - } else if original_item_name.starts_with("MY_PREFIXED_") { + } else if item_info.name.starts_with("MY_PREFIXED_") { Some( - original_item_name + item_info + .name .trim_start_matches("MY_PREFIXED_") .to_string(), ) @@ -145,6 +148,48 @@ impl ParseCallbacks for MacroCallback { vec![] } } + + fn modify_macro(&self, _name: &str, tokens: &mut Vec) { + // Handle macros dealing with bit positions of the format HI:LO + if tokens.len() == 4 && tokens[2].kind == TokenKind::Punctuation { + if let Ok(colon) = std::str::from_utf8(&tokens[2].raw) { + if colon != ":" { + return; + } + let high = match std::str::from_utf8(&tokens[1].raw) { + Ok(s) => { + if let Ok(val) = s.parse::() { + val + } else { + return; + } + } + Err(_) => { + return; + } + }; + + let low = match std::str::from_utf8(&tokens[3].raw) { + Ok(s) => { + if let Ok(val) = s.parse::() { + val + } else { + return; + } + } + Err(_) => { + return; + } + }; + let value: u32 = ((high as u32) << 16) | low as u32; + tokens[1] = Token::from(( + TokenKind::Literal, + value.to_string().as_bytes(), + )); + tokens.truncate(2); + } + } + } } impl Drop for MacroCallback { @@ -183,7 +228,7 @@ fn setup_macro_test() { let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); let out_rust_file = out_path.join("test.rs"); let out_rust_file_relative = out_rust_file - .strip_prefix(std::env::current_dir().unwrap().parent().unwrap()) + .strip_prefix(env::current_dir().unwrap().parent().unwrap()) .unwrap(); let out_dep_file = out_path.join("test.d"); @@ -206,6 +251,10 @@ fn setup_macro_test() { .blocklist_function("my_prefixed_function_to_remove") .constified_enum("my_prefixed_enum_to_be_constified") .opaque_type("my_prefixed_templated_foo") + .new_type_alias("MyInt") + .new_type_alias("MyBool") + .new_type_alias("MyFloat") + .new_type_alias("MyChar") .new_type_alias("TestDeriveOnAlias") .depfile(out_rust_file_relative.display().to_string(), &out_dep_file) .generate() @@ -243,7 +292,8 @@ fn setup_wrap_static_fns_test() { .expect("Path could not be converted to a str"); // generate external bindings with the external .c and .h files - let bindings = Builder::default() + #[allow(unused_mut)] + let mut builder = Builder::default() .header(input_header_file_path_str) .parse_callbacks(Box::new( bindgen::CargoCallbacks::new().rerun_on_header_files(true), @@ -253,25 +303,40 @@ fn setup_wrap_static_fns_test() { .wrap_static_fns_path( out_path.join("wrap_static_fns").display().to_string(), ) - .clang_arg("-DUSE_VA_HEADER") - .generate() - .expect("Unable to generate bindings"); + .clang_arg("-DUSE_VA_HEADER"); + + // aarch64-linux has a bug, remove again when it is solved: + // https://github.com/rust-lang/rust-bindgen/issues/3234 + #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + { + builder = builder.clang_arg("-DDISABLE_VA"); + } + + let bindings = builder.generate().expect("Unable to generate bindings"); println!("cargo:rustc-link-lib=static=wrap_static_fns"); // tell cargo to link libextern - println!("bindings generated: {}", bindings); + println!("bindings generated: {bindings}"); let obj_path = out_path.join("wrap_static_fns.o"); let lib_path = out_path.join("libwrap_static_fns.a"); // build the external files to check if they work - let clang_output = std::process::Command::new("clang") + let mut command = std::process::Command::new("clang"); + command .arg("-c") .arg("-o") .arg(&obj_path) .arg(out_path.join("wrap_static_fns.c")) - .arg("-DUSE_VA_HEADER") - .output() - .expect("`clang` command error"); + .arg("-DUSE_VA_HEADER"); + + // aarch64-linux has a bug, remove again when it is solved: + // https://github.com/rust-lang/rust-bindgen/issues/3234 + #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + { + command.arg("-DDISABLE_VA"); + } + + let clang_output = command.output().expect("`clang` command error"); if !clang_output.status.success() { panic!( "Could not compile object file:\n{}", diff --git a/bindgen-integration/cpp/Test.h b/bindgen-integration/cpp/Test.h index 81a921b5f8..25858b2790 100644 --- a/bindgen-integration/cpp/Test.h +++ b/bindgen-integration/cpp/Test.h @@ -22,6 +22,8 @@ #define TESTMACRO_STRING_EXPR ("string") #define TESTMACRO_STRING_FUNC_NON_UTF8(x) (x "��") /* invalid UTF-8 on purpose */ +#define TESTMACRO_COLON_VALUE 1:2 + enum { MY_ANNOYING_MACRO = #define MY_ANNOYING_MACRO 1 @@ -244,3 +246,16 @@ enum MyOrderedEnum { // Used to test custom derives on new-type alias. See `test_custom_derive`. typedef int TestDeriveOnAlias; + +// Used to test new-type alias constants. See `test_new_type_alias_const`. +typedef int MyInt; +const MyInt MY_INT = 5; + +typedef bool MyBool; +const MyBool MY_BOOL = true; + +typedef float MyFloat; +const MyFloat MY_FLOAT = 1.23f; + +typedef char MyChar; +const MyChar MY_CHAR = 'a'; diff --git a/bindgen-integration/src/lib.rs b/bindgen-integration/src/lib.rs index 48cfe092d2..8c31121b4b 100755 --- a/bindgen-integration/src/lib.rs +++ b/bindgen-integration/src/lib.rs @@ -178,19 +178,18 @@ fn test_bitfields_seventh() { fn test_bitfield_constructors() { use std::mem; let mut first = bindings::bitfields::First { - _bitfield_align_1: [], _bitfield_1: bindings::bitfields::First::new_bitfield_1(1, 2, 3), }; assert!(unsafe { first.assert(1, 2, 3) }); let mut second = bindings::bitfields::Second { - _bitfield_align_1: [], + _bindgen_align: [], _bitfield_1: bindings::bitfields::Second::new_bitfield_1(1337, true), }; assert!(unsafe { second.assert(1337, true) }); let mut third = bindings::bitfields::Third { - _bitfield_align_1: [], + _bindgen_align: [], _bitfield_1: bindings::bitfields::Third::new_bitfield_1( 42, false, @@ -254,12 +253,12 @@ fn test_item_rename() { #[test] fn test_matching_with_rename() { assert_eq!(bindings::enum_to_be_constified_THREE, 3); - assert_eq!(unsafe { bindings::TEMPLATED_CONST_VALUE.len() }, 30); + assert_eq!(unsafe { bindings::TEMPLATED_CONST_VALUE.0.len() }, 30); } #[test] fn test_macro_customintkind_path() { - let v: &std::any::Any = &bindings::TESTMACRO_CUSTOMINTKIND_PATH; + let v: &dyn std::any::Any = &bindings::TESTMACRO_CUSTOMINTKIND_PATH; assert!(v.is::()) } @@ -336,12 +335,31 @@ fn test_wrap_static_fns() { extern_bindings::takes_qualified(&(&5 as *const _) as *const _); assert_eq!(5, tq); - let wv1 = extern_bindings::wrap_as_variadic_fn1_wrapped(0); - assert_eq!(0, wv1); + // aarch64-linux has a bug, enable again when it is solved: + // https://github.com/rust-lang/rust-bindgen/issues/3234 + #[cfg(not(all(target_arch = "aarch64", target_os = "linux")))] + { + let wv1 = extern_bindings::wrap_as_variadic_fn1_wrapped(0); + assert_eq!(0, wv1); - let wv1 = extern_bindings::wrap_as_variadic_fn1_wrapped(2, 5, 3); - assert_eq!(8, wv1); + let wv1 = extern_bindings::wrap_as_variadic_fn1_wrapped(2, 5, 3); + assert_eq!(8, wv1); - extern_bindings::wrap_as_variadic_fn2_wrapped(1, 2); + extern_bindings::wrap_as_variadic_fn2_wrapped(1, 2); + } } } + +#[test] +fn test_colon_define() { + let gold: u32 = (1u32 << 16) | 2; + assert_eq!(gold, bindings::TESTMACRO_COLON_VALUE); +} + +#[test] +fn test_new_type_alias_const() { + assert_eq!(bindings::MY_INT.0, 5); + assert_eq!(bindings::MY_BOOL.0, true); + assert_eq!(bindings::MY_FLOAT.0, 1.23f32); + assert_eq!(bindings::MY_CHAR.0, b'a' as std::ffi::c_char); +} diff --git a/bindgen-tests/Cargo.toml b/bindgen-tests/Cargo.toml index 47fc0b8ca0..77a28ca3cb 100644 --- a/bindgen-tests/Cargo.toml +++ b/bindgen-tests/Cargo.toml @@ -1,20 +1,22 @@ +lints.workspace = true + [package] name = "bindgen-tests" -edition = "2018" version = "0.1.0" publish = false +rust-version.workspace = true +edition.workspace = true [dev-dependencies] -bindgen = { path = "../bindgen", features = ["__cli", "experimental"] } -clap = { version = "4", features = ["derive"] } -clap_complete = "4" -shlex = "1" -prettyplease = { version = "0.2.7", features = ["verbatim"] } -proc-macro2 = { version = "1", default-features = false } -syn = { version = "2.0" } -tempfile = "3" -similar = { version = "2.2.1", features = ["inline"] } -owo-colors = "3.5.0" +bindgen = { workspace = true, default-features = true, features = ["__cli", "experimental"] } +owo-colors.workspace = true +prettyplease = { workspace = true, features = ["verbatim"] } +proc-macro2.workspace = true +regex.workspace = true +shlex.workspace = true +similar = { workspace = true, features = ["inline"] } +syn.workspace = true +tempfile.workspace = true [features] logging = ["bindgen/logging"] diff --git a/bindgen-tests/build.rs b/bindgen-tests/build.rs index 6b2f2c7274..cf929b4b65 100644 --- a/bindgen-tests/build.rs +++ b/bindgen-tests/build.rs @@ -1,6 +1,5 @@ use std::char; use std::env; -use std::ffi::OsStr; use std::fs::{self, File}; use std::io::Write; use std::path::{Path, PathBuf}; @@ -12,10 +11,9 @@ pub fn main() { let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); let headers_dir = manifest_dir.join("tests").join("headers"); - let headers = match fs::read_dir(headers_dir) { - Ok(dir) => dir, + let Ok(headers) = fs::read_dir(headers_dir) else { // We may not have headers directory after packaging. - Err(..) => return, + return; }; let entries = @@ -24,24 +22,21 @@ pub fn main() { println!("cargo:rerun-if-changed=tests/headers"); for entry in entries { - match entry.path().extension().and_then(OsStr::to_str) { - Some("h") | Some("hpp") => { - let func = entry - .file_name() - .to_str() - .unwrap() - .replace(|c| !char::is_alphanumeric(c), "_") - .replace("__", "_") - .to_lowercase(); - writeln!( - dst, - "test_header!(header_{}, {:?});", - func, - entry.path(), - ) + // TODO: file_is_cpp() in bindgen/lib.rs checks for hpp,hxx,hh, and h++ - should this be consistent? + if entry.path().extension().is_some_and(|ext| { + ext.eq_ignore_ascii_case("h") || ext.eq_ignore_ascii_case("hpp") + }) { + let func = entry + .file_name() + .to_str() + .unwrap() + .replace(|c| !char::is_alphanumeric(c), "_") + .replace("__", "_") + .to_lowercase(); + // We actually want the quotes and escape + #[allow(clippy::unnecessary_debug_formatting)] + writeln!(dst, "test_header!(header_{func}, {:?});", entry.path()) .unwrap(); - } - _ => {} } } diff --git a/bindgen-tests/tests/expectations/Cargo.toml b/bindgen-tests/tests/expectations/Cargo.toml index adb95d56d2..975fd16678 100644 --- a/bindgen-tests/tests/expectations/Cargo.toml +++ b/bindgen-tests/tests/expectations/Cargo.toml @@ -7,10 +7,40 @@ authors = [ "Emilio Cobos Álvarez ", "The Servo project developers", ] -edition = "2018" publish = false +rust-version.workspace = true +edition.workspace = true [dependencies] -block = "0.1" -libloading = "0.7" -objc = "0.2" +block.workspace = true +libloading.workspace = true +objc.workspace = true + +# Both of these sections need to be copied here from the workspace because +# Cargo currently does not allow overriding workspace settings in a member +[lints.rust] +### FIXME: these might need to be fixed, +### esp the calling convention, because it is a hard error now +# deprecated = "allow" +# invalid-value = "allow" +# unsupported_calling_conventions = "allow" +# +# Different from the workspace +dead_code = "allow" +non-snake-case = "allow" +non_camel_case_types = "allow" +non_upper_case_globals = "allow" +unexpected-cfgs = "allow" +unused_qualifications = "allow" + +[lints.clippy] +disallowed-names = "allow" +manual-c-str-literals = "allow" +missing-safety-doc = "allow" +op-ref = "allow" +ptr-offset-with-cast = "allow" +semicolon_if_nothing_returned = "allow" +too-many-arguments = "allow" +transmute-int-to-bool = "allow" +unnecessary-cast = "allow" +useless-transmute = "allow" diff --git a/bindgen-tests/tests/expectations/build.rs b/bindgen-tests/tests/expectations/build.rs index 6136823e21..f4ded7e12d 100644 --- a/bindgen-tests/tests/expectations/build.rs +++ b/bindgen-tests/tests/expectations/build.rs @@ -47,10 +47,9 @@ fn main() { test_string.push_str(&format!( r###" #[path = "{}"] -mod {}; +mod {module_name}; "###, path.display().to_string().replace('\\', "\\\\"), - module_name, )); } } diff --git a/bindgen-tests/tests/expectations/lib.rs b/bindgen-tests/tests/expectations/lib.rs index 562dc5548d..e69de29bb2 100755 --- a/bindgen-tests/tests/expectations/lib.rs +++ b/bindgen-tests/tests/expectations/lib.rs @@ -1,3 +0,0 @@ -#![allow(dead_code)] -#![allow(non_camel_case_types)] -#![allow(non_upper_case_globals)] diff --git a/bindgen-tests/tests/expectations/tests/16-byte-alignment_1_0.rs b/bindgen-tests/tests/expectations/tests/16-byte-alignment_1_0.rs deleted file mode 100644 index 06d008982c..0000000000 --- a/bindgen-tests/tests/expectations/tests/16-byte-alignment_1_0.rs +++ /dev/null @@ -1,299 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_ipv4_tuple { - pub src_addr: u32, - pub dst_addr: u32, - pub __bindgen_anon_1: rte_ipv4_tuple__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_ipv4_tuple__bindgen_ty_1 { - pub __bindgen_anon_1: __BindgenUnionField< - rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1, - >, - pub sctp_tag: __BindgenUnionField, - pub bindgen_union_field: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1 { - pub dport: u16, - pub sport: u16, -} -#[test] -fn bindgen_test_layout_rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dport) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1::dport", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).sport) as usize - ptr as usize }, - 2usize, - "Offset of field: rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1::sport", - ); -} -impl Clone for rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_ipv4_tuple__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of rte_ipv4_tuple__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_ipv4_tuple__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).sctp_tag) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_ipv4_tuple__bindgen_ty_1::sctp_tag", - ); -} -impl Clone for rte_ipv4_tuple__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_ipv4_tuple() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, - "Size of rte_ipv4_tuple", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_ipv4_tuple", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).src_addr) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_ipv4_tuple::src_addr", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dst_addr) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_ipv4_tuple::dst_addr", - ); -} -impl Clone for rte_ipv4_tuple { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_ipv6_tuple { - pub src_addr: [u8; 16usize], - pub dst_addr: [u8; 16usize], - pub __bindgen_anon_1: rte_ipv6_tuple__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_ipv6_tuple__bindgen_ty_1 { - pub __bindgen_anon_1: __BindgenUnionField< - rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1, - >, - pub sctp_tag: __BindgenUnionField, - pub bindgen_union_field: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1 { - pub dport: u16, - pub sport: u16, -} -#[test] -fn bindgen_test_layout_rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dport) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1::dport", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).sport) as usize - ptr as usize }, - 2usize, - "Offset of field: rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1::sport", - ); -} -impl Clone for rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_ipv6_tuple__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of rte_ipv6_tuple__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_ipv6_tuple__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).sctp_tag) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_ipv6_tuple__bindgen_ty_1::sctp_tag", - ); -} -impl Clone for rte_ipv6_tuple__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_ipv6_tuple() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 36usize, - "Size of rte_ipv6_tuple", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_ipv6_tuple", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).src_addr) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_ipv6_tuple::src_addr", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dst_addr) as usize - ptr as usize }, - 16usize, - "Offset of field: rte_ipv6_tuple::dst_addr", - ); -} -impl Clone for rte_ipv6_tuple { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Copy)] -pub struct rte_thash_tuple { - pub v4: __BindgenUnionField, - pub v6: __BindgenUnionField, - pub bindgen_union_field: [u8; 48usize], -} -#[test] -fn bindgen_test_layout_rte_thash_tuple() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 48usize, - "Size of rte_thash_tuple", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).v4) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_thash_tuple::v4", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).v6) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_thash_tuple::v6", - ); -} -impl Clone for rte_thash_tuple { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_thash_tuple { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} diff --git a/bindgen-tests/tests/expectations/tests/abi-override.rs b/bindgen-tests/tests/expectations/tests/abi-override.rs index 13132f9c45..369bfd8d32 100644 --- a/bindgen-tests/tests/expectations/tests/abi-override.rs +++ b/bindgen-tests/tests/expectations/tests/abi-override.rs @@ -1,14 +1,15 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "fastcall" { +#![cfg(target = "i686-pc-windows-msvc")] +unsafe extern "fastcall" { pub fn foo(); } -extern "stdcall" { +unsafe extern "stdcall" { pub fn bar(); } -extern "C" { +unsafe extern "C" { pub fn baz(); } -extern "system" { +unsafe extern "system" { pub fn qux(); } pub type boo = ::std::option::Option; diff --git a/bindgen-tests/tests/expectations/tests/abi_variadic_function.rs b/bindgen-tests/tests/expectations/tests/abi_variadic_function.rs index 3cb7248c93..b57ddafd32 100644 --- a/bindgen-tests/tests/expectations/tests/abi_variadic_function.rs +++ b/bindgen-tests/tests/expectations/tests/abi_variadic_function.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z1bcz"] pub fn b(arg1: ::std::os::raw::c_char, ...) -> ::std::os::raw::c_char; } diff --git a/bindgen-tests/tests/expectations/tests/allowlist-file.rs b/bindgen-tests/tests/expectations/tests/allowlist-file.rs index a0053653f3..b1fb170de0 100644 --- a/bindgen-tests/tests/expectations/tests/allowlist-file.rs +++ b/bindgen-tests/tests/expectations/tests/allowlist-file.rs @@ -1,10 +1,10 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub const SOME_DEFUN: u32 = 123; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z12SomeFunctionv"] pub fn SomeFunction(); } -extern "C" { +unsafe extern "C" { pub static mut someVar: ::std::os::raw::c_int; } #[repr(C)] @@ -17,7 +17,7 @@ const _: () = { ["Size of someClass"][::std::mem::size_of::() - 1usize]; ["Alignment of someClass"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN9someClass16somePublicMethodEi"] pub fn someClass_somePublicMethod(this: *mut someClass, foo: ::std::os::raw::c_int); } @@ -27,10 +27,10 @@ impl someClass { someClass_somePublicMethod(self, foo) } } -extern "C" { +unsafe extern "C" { pub fn ExternFunction(); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3foo18NamespacedFunctionEv"] pub fn foo_NamespacedFunction(); } diff --git a/bindgen-tests/tests/expectations/tests/allowlist_fix.rs b/bindgen-tests/tests/expectations/tests/allowlist_fix.rs index e3ce7bc100..772772c56c 100644 --- a/bindgen-tests/tests/expectations/tests/allowlist_fix.rs +++ b/bindgen-tests/tests/expectations/tests/allowlist_fix.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub enum Test {} -extern "C" { +unsafe extern "C" { pub fn Servo_Test(a: *mut Test); } diff --git a/bindgen-tests/tests/expectations/tests/allowlist_item.rs b/bindgen-tests/tests/expectations/tests/allowlist_item.rs index e5aa4b2172..93eab7e147 100644 --- a/bindgen-tests/tests/expectations/tests/allowlist_item.rs +++ b/bindgen-tests/tests/expectations/tests/allowlist_item.rs @@ -11,6 +11,6 @@ const _: () = { ["Alignment of Foo"][::std::mem::align_of::() - 4usize]; ["Offset of field: Foo::field"][::std::mem::offset_of!(Foo, field) - 0usize]; }; -extern "C" { +unsafe extern "C" { pub fn FooNew(value: ::std::os::raw::c_int) -> Foo; } diff --git a/bindgen-tests/tests/expectations/tests/anon_struct_in_union_1_0.rs b/bindgen-tests/tests/expectations/tests/anon_struct_in_union_1_0.rs deleted file mode 100644 index 5a6e3ca477..0000000000 --- a/bindgen-tests/tests/expectations/tests/anon_struct_in_union_1_0.rs +++ /dev/null @@ -1,127 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct s { - pub u: s__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct s__bindgen_ty_1 { - pub field: __BindgenUnionField, - pub bindgen_union_field: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct s__bindgen_ty_1_inner { - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_s__bindgen_ty_1_inner() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of s__bindgen_ty_1_inner", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of s__bindgen_ty_1_inner", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: s__bindgen_ty_1_inner::b", - ); -} -impl Clone for s__bindgen_ty_1_inner { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_s__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of s__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of s__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).field) as usize - ptr as usize }, - 0usize, - "Offset of field: s__bindgen_ty_1::field", - ); -} -impl Clone for s__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_s() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of s"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of s"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).u) as usize - ptr as usize }, - 0usize, - "Offset of field: s::u", - ); -} -impl Clone for s { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/anon_union_1_0.rs b/bindgen-tests/tests/expectations/tests/anon_union_1_0.rs deleted file mode 100644 index 29b13d010d..0000000000 --- a/bindgen-tests/tests/expectations/tests/anon_union_1_0.rs +++ /dev/null @@ -1,125 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct TErrorResult { - pub mResult: ::std::os::raw::c_int, - pub __bindgen_anon_1: TErrorResult__bindgen_ty_1, - pub mMightHaveUnreported: bool, - pub mUnionState: TErrorResult_UnionState, -} -pub const TErrorResult_UnionState_HasException: TErrorResult_UnionState = TErrorResult_UnionState::HasMessage; -#[repr(i32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum TErrorResult_UnionState { - HasMessage = 0, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct TErrorResult_Message { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct TErrorResult_DOMExceptionInfo { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct TErrorResult__bindgen_ty_1 { - pub mMessage: __BindgenUnionField<*mut TErrorResult_Message>, - pub mDOMExceptionInfo: __BindgenUnionField<*mut TErrorResult_DOMExceptionInfo>, - pub bindgen_union_field: u64, -} -impl Default for TErrorResult { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct ErrorResult { - pub _base: TErrorResult, -} -#[test] -fn bindgen_test_layout_ErrorResult() { - assert_eq!(::std::mem::size_of::(), 24usize, "Size of ErrorResult"); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of ErrorResult", - ); -} -impl Clone for ErrorResult { - fn clone(&self) -> Self { - *self - } -} -impl Default for ErrorResult { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[test] -fn __bindgen_test_layout_TErrorResult_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - "Size of template specialization: TErrorResult_open0_int_close0", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Align of template specialization: TErrorResult_open0_int_close0", - ); -} diff --git a/bindgen-tests/tests/expectations/tests/arg_keyword.rs b/bindgen-tests/tests/expectations/tests/arg_keyword.rs index e7dd10b048..5a48aba011 100644 --- a/bindgen-tests/tests/expectations/tests/arg_keyword.rs +++ b/bindgen-tests/tests/expectations/tests/arg_keyword.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z3fooPKc"] pub fn foo(type_: *const ::std::os::raw::c_char); } diff --git a/bindgen-tests/tests/expectations/tests/atomic-constant.rs b/bindgen-tests/tests/expectations/tests/atomic-constant.rs index bd3c18697b..344e632085 100644 --- a/bindgen-tests/tests/expectations/tests/atomic-constant.rs +++ b/bindgen-tests/tests/expectations/tests/atomic-constant.rs @@ -1,7 +1,7 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub static mut a: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub static mut b: ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result.rs b/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result.rs index 07eb7a80f6..ec152e1543 100644 --- a/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result.rs +++ b/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result.rs @@ -4,12 +4,12 @@ pub struct Foo { pub _address: u8, } -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!(::std::mem::size_of::(), 1usize, "Size of Foo"); - assert_eq!(::std::mem::align_of::(), 1usize, "Alignment of Foo"); -} -extern "C" { +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { #[must_use] #[link_name = "\u{1}_ZN3Foo3fooEi"] pub fn Foo_foo(this: *mut Foo, arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; @@ -21,7 +21,7 @@ impl Foo { Foo_foo(self, arg1) } } -extern "C" { +unsafe extern "C" { #[must_use] #[link_name = "\u{1}_Z3fooi"] pub fn foo(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; diff --git a/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result_no_attribute_detection.rs b/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result_no_attribute_detection.rs index aa01540b0e..f0fb434bcb 100644 --- a/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result_no_attribute_detection.rs +++ b/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result_no_attribute_detection.rs @@ -4,12 +4,12 @@ pub struct Foo { pub _address: u8, } -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!(::std::mem::size_of::(), 1usize, "Size of Foo"); - assert_eq!(::std::mem::align_of::(), 1usize, "Alignment of Foo"); -} -extern "C" { +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo3fooEi"] pub fn Foo_foo(this: *mut Foo, arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; } @@ -19,7 +19,7 @@ impl Foo { Foo_foo(self, arg1) } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z3fooi"] pub fn foo(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result_pre_1_27.rs b/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result_pre_1_27.rs deleted file mode 100644 index f545f9e6bb..0000000000 --- a/bindgen-tests/tests/expectations/tests/attribute_warn_unused_result_pre_1_27.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct Foo { - pub _address: u8, -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of Foo"][::std::mem::size_of::() - 1usize]; - ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; -}; -extern "C" { - #[link_name = "\u{1}_ZN3Foo3fooEi"] - pub fn Foo_foo(this: *mut Foo, arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; -} -impl Foo { - #[inline] - pub unsafe fn foo(&mut self, arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int { - Foo_foo(self, arg1) - } -} -extern "C" { - #[link_name = "\u{1}_Z3fooi"] - pub fn foo(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int; -} diff --git a/bindgen-tests/tests/expectations/tests/auto.rs b/bindgen-tests/tests/expectations/tests/auto.rs index 0173f0409f..ba93e7a20b 100644 --- a/bindgen-tests/tests/expectations/tests/auto.rs +++ b/bindgen-tests/tests/expectations/tests/auto.rs @@ -15,7 +15,7 @@ const _: () = { pub struct Bar { pub _address: u8, } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z5Test2v"] pub fn Test2() -> ::std::os::raw::c_uint; } diff --git a/bindgen-tests/tests/expectations/tests/bindgen-union-inside-namespace.rs b/bindgen-tests/tests/expectations/tests/bindgen-union-inside-namespace.rs index 70f9216a68..2c8d2e5713 100644 --- a/bindgen-tests/tests/expectations/tests/bindgen-union-inside-namespace.rs +++ b/bindgen-tests/tests/expectations/tests/bindgen-union-inside-namespace.rs @@ -1,81 +1,31 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] pub mod root { - #[repr(C)] - pub struct __BindgenUnionField(::std::marker::PhantomData); - impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } - } - impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } - } - impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } - } - impl ::std::marker::Copy for __BindgenUnionField {} - impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } - } - impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} - } - impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } - } - impl ::std::cmp::Eq for __BindgenUnionField {} #[allow(unused_imports)] use self::super::root; pub mod foo { #[allow(unused_imports)] use self::super::super::root; #[repr(C)] - #[derive(Debug, Default, Copy)] - pub struct Bar { - pub foo: root::__BindgenUnionField<::std::os::raw::c_int>, - pub bar: root::__BindgenUnionField<::std::os::raw::c_int>, - pub bindgen_union_field: u32, - } - #[test] - fn bindgen_test_layout_Bar() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of Bar"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of Bar"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).foo) as usize - ptr as usize }, - 0usize, - "Offset of field: Bar::foo", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).bar) as usize - ptr as usize }, - 0usize, - "Offset of field: Bar::bar", - ); - } - impl Clone for Bar { - fn clone(&self) -> Self { - *self + #[derive(Copy, Clone)] + pub union Bar { + pub foo: ::std::os::raw::c_int, + pub bar: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 4usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Bar::foo"][::std::mem::offset_of!(Bar, foo) - 0usize]; + ["Offset of field: Bar::bar"][::std::mem::offset_of!(Bar, bar) - 0usize]; + }; + impl Default for Bar { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } } } } diff --git a/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs b/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs index 475cbae837..783f0ef7a9 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,11 +126,28 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct MuchBitfield { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 5usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -107,6 +168,30 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m0_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_m0_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m1(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } } @@ -118,6 +203,30 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m1_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_m1_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m2(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u8) } } @@ -129,6 +238,30 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m2_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_m2_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 2usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m3(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u8) } } @@ -140,6 +273,30 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m3_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 3usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_m3_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 3usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m4(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u8) } } @@ -151,6 +308,30 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m4_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_m4_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 4usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m5(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u8) } } @@ -162,6 +343,30 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m5_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 5usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_m5_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 5usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m6(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u8) } } @@ -173,6 +378,30 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m6_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 6usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_m6_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 6usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m7(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u8) } } @@ -184,6 +413,30 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m7_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 7usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_m7_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 7usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m8(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u8) } } @@ -195,6 +448,30 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m8_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 8usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_m8_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 8usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m9(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u8) } } @@ -206,6 +483,30 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m9_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 9usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_m9_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 9usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m10(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 1u8) as u8) } } @@ -217,6 +518,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m10_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 10usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m10_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 10usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m11(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 1u8) as u8) } } @@ -228,6 +554,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m11_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 11usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m11_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 11usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m12(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 1u8) as u8) } } @@ -239,6 +590,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m12_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 12usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m12_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 12usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m13(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(13usize, 1u8) as u8) } } @@ -250,6 +626,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m13_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 13usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m13_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 13usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m14(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 1u8) as u8) } } @@ -261,6 +662,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m14_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 14usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m14_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 14usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m15(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(15usize, 1u8) as u8) } } @@ -272,6 +698,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m15_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 15usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m15_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 15usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m16(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 1u8) as u8) } } @@ -283,6 +734,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m16_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 16usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m16_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 16usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m17(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(17usize, 1u8) as u8) } } @@ -294,6 +770,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m17_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 17usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m17_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 17usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m18(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(18usize, 1u8) as u8) } } @@ -305,6 +806,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m18_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 18usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m18_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 18usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m19(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(19usize, 1u8) as u8) } } @@ -316,6 +842,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m19_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 19usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m19_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 19usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m20(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(20usize, 1u8) as u8) } } @@ -327,6 +878,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m20_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 20usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m20_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 20usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m21(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(21usize, 1u8) as u8) } } @@ -338,6 +914,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m21_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 21usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m21_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 21usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m22(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(22usize, 1u8) as u8) } } @@ -349,6 +950,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m22_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 22usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m22_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 22usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m23(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(23usize, 1u8) as u8) } } @@ -360,6 +986,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m23_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 23usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m23_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 23usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m24(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 1u8) as u8) } } @@ -371,6 +1022,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m24_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 24usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m24_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 24usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m25(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(25usize, 1u8) as u8) } } @@ -382,6 +1058,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m25_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 25usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m25_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 25usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m26(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(26usize, 1u8) as u8) } } @@ -393,6 +1094,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m26_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 26usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m26_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 26usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m27(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(27usize, 1u8) as u8) } } @@ -404,6 +1130,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m27_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 27usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m27_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 27usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m28(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(28usize, 1u8) as u8) } } @@ -415,6 +1166,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m28_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 28usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m28_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 28usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m29(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(29usize, 1u8) as u8) } } @@ -426,6 +1202,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m29_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 29usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m29_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 29usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m30(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(30usize, 1u8) as u8) } } @@ -437,6 +1238,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m30_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 30usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m30_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 30usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m31(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(31usize, 1u8) as u8) } } @@ -448,6 +1274,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m31_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 31usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m31_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 31usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn m32(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(32usize, 1u8) as u8) } } @@ -459,6 +1310,31 @@ impl MuchBitfield { } } #[inline] + pub unsafe fn m32_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 32usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_m32_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 32usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( m0: ::std::os::raw::c_char, m1: ::std::os::raw::c_char, diff --git a/bindgen-tests/tests/expectations/tests/bitfield-enum-basic.rs b/bindgen-tests/tests/expectations/tests/bitfield-enum-basic.rs index adc4690c86..aecb9dc639 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-enum-basic.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-enum-basic.rs @@ -1,14 +1,8 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] impl Foo { pub const Bar: Foo = Foo(2); -} -impl Foo { pub const Baz: Foo = Foo(4); -} -impl Foo { pub const Duplicated: Foo = Foo(4); -} -impl Foo { pub const Negative: Foo = Foo(-3); } impl ::std::ops::BitOr for Foo { @@ -42,14 +36,8 @@ impl ::std::ops::BitAndAssign for Foo { pub struct Foo(pub ::std::os::raw::c_int); impl Buz { pub const Bar: Buz = Buz(2); -} -impl Buz { pub const Baz: Buz = Buz(4); -} -impl Buz { pub const Duplicated: Buz = Buz(4); -} -impl Buz { pub const Negative: Buz = Buz(-3); } impl ::std::ops::BitOr for Buz { diff --git a/bindgen-tests/tests/expectations/tests/bitfield-enum-repr-c.rs b/bindgen-tests/tests/expectations/tests/bitfield-enum-repr-c.rs index 0403e844e2..df5a69eddd 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-enum-repr-c.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-enum-repr-c.rs @@ -1,14 +1,8 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] impl Foo { pub const Bar: Foo = Foo(2); -} -impl Foo { pub const Baz: Foo = Foo(4); -} -impl Foo { pub const Duplicated: Foo = Foo(4); -} -impl Foo { pub const Negative: Foo = Foo(-3); } impl ::std::ops::BitOr for Foo { @@ -37,6 +31,6 @@ impl ::std::ops::BitAndAssign for Foo { self.0 &= rhs.0; } } -#[repr(C)] +#[repr(transparent)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Foo(pub ::std::os::raw::c_int); diff --git a/bindgen-tests/tests/expectations/tests/bitfield-enum-repr-transparent.rs b/bindgen-tests/tests/expectations/tests/bitfield-enum-repr-transparent.rs index 0b5202dfe3..df5a69eddd 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-enum-repr-transparent.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-enum-repr-transparent.rs @@ -1,14 +1,8 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] impl Foo { pub const Bar: Foo = Foo(2); -} -impl Foo { pub const Baz: Foo = Foo(4); -} -impl Foo { pub const Duplicated: Foo = Foo(4); -} -impl Foo { pub const Negative: Foo = Foo(-3); } impl ::std::ops::BitOr for Foo { diff --git a/bindgen-tests/tests/expectations/tests/bitfield-large.rs b/bindgen-tests/tests/expectations/tests/bitfield-large.rs index 27118083d5..5d614ab936 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-large.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-large.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,12 +126,29 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[repr(align(16))] #[derive(Debug, Default, Copy, Clone)] pub struct HasBigBitfield { - pub _bitfield_align_1: [u64; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 16usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -108,6 +169,31 @@ impl HasBigBitfield { } } #[inline] + pub unsafe fn x_raw(this: *const Self) -> i128 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 128u8) + as u128, + ) + } + } + #[inline] + pub unsafe fn set_x_raw(this: *mut Self, val: i128) { + unsafe { + let val: u128 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 128u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1(x: i128) -> __BindgenBitfieldUnit<[u8; 16usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 16usize]> = Default::default(); __bindgen_bitfield_unit @@ -126,7 +212,6 @@ impl HasBigBitfield { #[repr(align(16))] #[derive(Debug, Default, Copy, Clone)] pub struct HasTwoBigBitfields { - pub _bitfield_align_1: [u64; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 16usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -151,6 +236,31 @@ impl HasTwoBigBitfields { } } #[inline] + pub unsafe fn x_raw(this: *const Self) -> i128 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 80u8) + as u128, + ) + } + } + #[inline] + pub unsafe fn set_x_raw(this: *mut Self, val: i128) { + unsafe { + let val: u128 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 80u8, + val as u64, + ) + } + } + #[inline] pub fn y(&self) -> i128 { unsafe { ::std::mem::transmute(self._bitfield_1.get(80usize, 48u8) as u128) } } @@ -162,6 +272,31 @@ impl HasTwoBigBitfields { } } #[inline] + pub unsafe fn y_raw(this: *const Self) -> i128 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 80usize, 48u8) + as u128, + ) + } + } + #[inline] + pub unsafe fn set_y_raw(this: *mut Self, val: i128) { + unsafe { + let val: u128 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 80usize, + 48u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1(x: i128, y: i128) -> __BindgenBitfieldUnit<[u8; 16usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 16usize]> = Default::default(); __bindgen_bitfield_unit diff --git a/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs b/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs index 9e69bf9de5..3e676c53b5 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,20 +126,31 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } -#[repr(C, packed(4))] +#[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Test { pub foo: u64, - pub _bitfield_align_1: [u64; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, } -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of Test"][::std::mem::size_of::() - 16usize]; - ["Alignment of Test"][::std::mem::align_of::() - 4usize]; - ["Offset of field: Test::foo"][::std::mem::offset_of!(Test, foo) - 0usize]; -}; impl Test { #[inline] pub fn x(&self) -> u64 { @@ -109,6 +164,31 @@ impl Test { } } #[inline] + pub unsafe fn x_raw(this: *const Self) -> u64 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 56u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_x_raw(this: *mut Self, val: u64) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 56u8, + val as u64, + ) + } + } + #[inline] pub fn y(&self) -> u64 { unsafe { ::std::mem::transmute(self._bitfield_1.get(56usize, 8u8) as u64) } } @@ -120,6 +200,31 @@ impl Test { } } #[inline] + pub unsafe fn y_raw(this: *const Self) -> u64 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 56usize, 8u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_y_raw(this: *mut Self, val: u64) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 56usize, + 8u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1(x: u64, y: u64) -> __BindgenBitfieldUnit<[u8; 8usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default(); __bindgen_bitfield_unit diff --git a/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs b/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs index dd4286496c..09ca005589 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,11 +126,28 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Foo { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -94,15 +155,15 @@ const _: () = { ["Size of Foo"][::std::mem::size_of::() - 1usize]; ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo4typeEv"] pub fn Foo_type(this: *mut Foo) -> ::std::os::raw::c_char; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo9set_type_Ec"] pub fn Foo_set_type_(this: *mut Foo, c: ::std::os::raw::c_char); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo8set_typeEc"] pub fn Foo_set_type(this: *mut Foo, c: ::std::os::raw::c_char); } @@ -119,6 +180,35 @@ impl Foo { } } #[inline] + pub unsafe fn type__bindgen_bitfield_raw( + this: *const Self, + ) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 3u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_type__bindgen_bitfield_raw( + this: *mut Self, + val: ::std::os::raw::c_char, + ) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 3u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( type__bindgen_bitfield: ::std::os::raw::c_char, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { diff --git a/bindgen-tests/tests/expectations/tests/bitfield-template.rs b/bindgen-tests/tests/expectations/tests/bitfield-template.rs new file mode 100644 index 0000000000..eb454e0db4 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bitfield-template.rs @@ -0,0 +1,214 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit { + storage: Storage, +} +impl __BindgenBitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage } + } +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + fn extract_bit(byte: u8, index: usize) -> bool { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct foo { + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, + pub member: T, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, +} +impl Default for foo { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl foo { + #[inline] + pub fn b(&self) -> bool { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 8u8) as u8) } + } + #[inline] + pub fn set_b(&mut self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 8u8, val as u64) + } + } + #[inline] + pub unsafe fn b_raw(this: *const Self) -> bool { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 8u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 8u8, + val as u64, + ) + } + } + #[inline] + pub fn new_bitfield_1(b: bool) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 8u8, + { + let b: u8 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/bitfield_align.rs b/bindgen-tests/tests/expectations/tests/bitfield_align.rs index 828f176de9..0c70917fc5 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_align.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_align.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,13 +126,30 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] -#[repr(align(4))] #[derive(Debug, Default, Copy, Clone)] pub struct A { + pub _bindgen_align: [u32; 0], pub x: ::std::os::raw::c_uchar, - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, pub y: ::std::os::raw::c_uchar, } @@ -112,6 +173,31 @@ impl A { } } #[inline] + pub unsafe fn b1_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b1_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b2(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } } @@ -123,6 +209,31 @@ impl A { } } #[inline] + pub unsafe fn b2_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b2_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b3(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } } @@ -134,6 +245,31 @@ impl A { } } #[inline] + pub unsafe fn b3_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b3_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 2usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b4(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } } @@ -145,6 +281,31 @@ impl A { } } #[inline] + pub unsafe fn b4_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 3usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b4_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 3usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b5(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } } @@ -156,6 +317,31 @@ impl A { } } #[inline] + pub unsafe fn b5_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b5_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 4usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b6(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } } @@ -167,6 +353,31 @@ impl A { } } #[inline] + pub unsafe fn b6_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 5usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b6_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 5usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b7(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u32) } } @@ -178,6 +389,31 @@ impl A { } } #[inline] + pub unsafe fn b7_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 6usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b7_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 6usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b8(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) } } @@ -189,6 +425,31 @@ impl A { } } #[inline] + pub unsafe fn b8_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 7usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b8_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 7usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b9(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u32) } } @@ -200,6 +461,31 @@ impl A { } } #[inline] + pub unsafe fn b9_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 8usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b9_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 8usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b10(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u32) } } @@ -211,6 +497,31 @@ impl A { } } #[inline] + pub unsafe fn b10_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 9usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b10_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 9usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( b1: ::std::os::raw::c_uint, b2: ::std::os::raw::c_uint, @@ -320,7 +631,7 @@ impl A { #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct B { - pub _bitfield_align_1: [u32; 0], + pub _bindgen_align: [u32; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -341,6 +652,31 @@ impl B { } } #[inline] + pub unsafe fn foo_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 31u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_foo_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 31u8, + val as u64, + ) + } + } + #[inline] pub fn bar(&self) -> ::std::os::raw::c_uchar { unsafe { ::std::mem::transmute(self._bitfield_1.get(31usize, 1u8) as u8) } } @@ -352,6 +688,31 @@ impl B { } } #[inline] + pub unsafe fn bar_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 31usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_bar_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 31usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( foo: ::std::os::raw::c_uint, bar: ::std::os::raw::c_uchar, @@ -382,7 +743,6 @@ impl B { #[derive(Debug, Default, Copy, Clone)] pub struct C { pub x: ::std::os::raw::c_uchar, - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub baz: ::std::os::raw::c_uint, } @@ -406,6 +766,31 @@ impl C { } } #[inline] + pub unsafe fn b1_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b1_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b2(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } } @@ -417,6 +802,31 @@ impl C { } } #[inline] + pub unsafe fn b2_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b2_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( b1: ::std::os::raw::c_uint, b2: ::std::os::raw::c_uint, @@ -444,10 +854,9 @@ impl C { } } #[repr(C)] -#[repr(align(2))] #[derive(Debug, Default, Copy, Clone)] pub struct Date1 { - pub _bitfield_align_1: [u8; 0], + pub _bindgen_align: [u16; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, pub __bindgen_padding_0: u8, } @@ -469,6 +878,31 @@ impl Date1 { } } #[inline] + pub unsafe fn nWeekDay_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 3u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_nWeekDay_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 3u8, + val as u64, + ) + } + } + #[inline] pub fn nMonthDay(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 6u8) as u16) } } @@ -480,6 +914,31 @@ impl Date1 { } } #[inline] + pub unsafe fn nMonthDay_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 3usize, 6u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_nMonthDay_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 3usize, + 6u8, + val as u64, + ) + } + } + #[inline] pub fn nMonth(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 5u8) as u16) } } @@ -491,6 +950,31 @@ impl Date1 { } } #[inline] + pub unsafe fn nMonth_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 9usize, 5u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_nMonth_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 9usize, + 5u8, + val as u64, + ) + } + } + #[inline] pub fn nYear(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u16) } } @@ -502,6 +986,31 @@ impl Date1 { } } #[inline] + pub unsafe fn nYear_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 16usize, 8u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_nYear_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 16usize, + 8u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( nWeekDay: ::std::os::raw::c_ushort, nMonthDay: ::std::os::raw::c_ushort, @@ -549,10 +1058,9 @@ impl Date1 { } } #[repr(C)] -#[repr(align(2))] #[derive(Debug, Default, Copy, Clone)] pub struct Date2 { - pub _bitfield_align_1: [u8; 0], + pub _bindgen_align: [u16; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -573,6 +1081,31 @@ impl Date2 { } } #[inline] + pub unsafe fn nWeekDay_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 3u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_nWeekDay_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 3u8, + val as u64, + ) + } + } + #[inline] pub fn nMonthDay(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 6u8) as u16) } } @@ -584,6 +1117,31 @@ impl Date2 { } } #[inline] + pub unsafe fn nMonthDay_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 3usize, 6u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_nMonthDay_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 3usize, + 6u8, + val as u64, + ) + } + } + #[inline] pub fn nMonth(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 5u8) as u16) } } @@ -595,6 +1153,31 @@ impl Date2 { } } #[inline] + pub unsafe fn nMonth_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 9usize, 5u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_nMonth_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 9usize, + 5u8, + val as u64, + ) + } + } + #[inline] pub fn nYear(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u16) } } @@ -606,6 +1189,31 @@ impl Date2 { } } #[inline] + pub unsafe fn nYear_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 16usize, 8u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_nYear_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 16usize, + 8u8, + val as u64, + ) + } + } + #[inline] pub fn byte(&self) -> ::std::os::raw::c_uchar { unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 8u8) as u8) } } @@ -617,6 +1225,31 @@ impl Date2 { } } #[inline] + pub unsafe fn byte_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 24usize, 8u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_byte_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 24usize, + 8u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( nWeekDay: ::std::os::raw::c_ushort, nMonthDay: ::std::os::raw::c_ushort, @@ -674,10 +1307,9 @@ impl Date2 { } } #[repr(C)] -#[repr(align(2))] #[derive(Debug, Default, Copy, Clone)] pub struct Date3 { - pub _bitfield_align_1: [u8; 0], + pub _bindgen_align: [u16; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, pub byte: ::std::os::raw::c_uchar, } @@ -700,6 +1332,31 @@ impl Date3 { } } #[inline] + pub unsafe fn nWeekDay_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 3u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_nWeekDay_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 3u8, + val as u64, + ) + } + } + #[inline] pub fn nMonthDay(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 6u8) as u16) } } @@ -711,6 +1368,31 @@ impl Date3 { } } #[inline] + pub unsafe fn nMonthDay_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 3usize, 6u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_nMonthDay_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 3usize, + 6u8, + val as u64, + ) + } + } + #[inline] pub fn nMonth(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 5u8) as u16) } } @@ -722,6 +1404,31 @@ impl Date3 { } } #[inline] + pub unsafe fn nMonth_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 9usize, 5u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_nMonth_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 9usize, + 5u8, + val as u64, + ) + } + } + #[inline] pub fn nYear(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u16) } } @@ -733,6 +1440,31 @@ impl Date3 { } } #[inline] + pub unsafe fn nYear_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 16usize, 8u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_nYear_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 16usize, + 8u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( nWeekDay: ::std::os::raw::c_ushort, nMonthDay: ::std::os::raw::c_ushort, diff --git a/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs b/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs index b87af0c99c..b71bba18ad 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs @@ -16,10 +16,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -29,21 +26,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -66,6 +90,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -83,6 +127,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] @@ -95,7 +157,7 @@ pub enum MyEnum { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct TaggedPtr { - pub _bitfield_align_1: [u64; 0], + pub _bindgen_align: [u64; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -125,6 +187,31 @@ impl TaggedPtr { } } #[inline] + pub unsafe fn tag_raw(this: *const Self) -> MyEnum { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 2u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_tag_raw(this: *mut Self, val: MyEnum) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 2u8, + val as u64, + ) + } + } + #[inline] pub fn ptr(&self) -> ::std::os::raw::c_long { unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 62u8) as u64) } } @@ -136,6 +223,31 @@ impl TaggedPtr { } } #[inline] + pub unsafe fn ptr_raw(this: *const Self) -> ::std::os::raw::c_long { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 62u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_ptr_raw(this: *mut Self, val: ::std::os::raw::c_long) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 2usize, + 62u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( tag: MyEnum, ptr: ::std::os::raw::c_long, diff --git a/bindgen-tests/tests/expectations/tests/bitfield_large_overflow.rs b/bindgen-tests/tests/expectations/tests/bitfield_large_overflow.rs index 8967bb9856..ac5d75735e 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_large_overflow.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_large_overflow.rs @@ -1,15 +1,23 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C, align(8))] +pub struct __BindgenOpaqueArray8(pub T); +impl Default for __BindgenOpaqueArray8<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} #[repr(C)] -#[repr(align(8))] #[derive(Debug, Default, Copy, Clone)] pub struct _bindgen_ty_1 { - pub _bindgen_opaque_blob: [u64; 10usize], + pub _bindgen_align: [u64; 0], + pub _bindgen_opaque_blob: __BindgenOpaqueArray8<[u8; 80usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { ["Size of _bindgen_ty_1"][::std::mem::size_of::<_bindgen_ty_1>() - 80usize]; ["Alignment of _bindgen_ty_1"][::std::mem::align_of::<_bindgen_ty_1>() - 8usize]; }; -extern "C" { +unsafe extern "C" { pub static mut a: _bindgen_ty_1; } diff --git a/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs b/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs index b6fe8a5257..35117c74b6 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,11 +126,29 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct mach_msg_type_descriptor_t { - pub _bitfield_align_1: [u32; 0], + pub _bindgen_align: [u32; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -111,6 +173,31 @@ impl mach_msg_type_descriptor_t { } } #[inline] + pub unsafe fn pad3_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 24u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_pad3_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 24u8, + val as u64, + ) + } + } + #[inline] pub fn type_(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 8u8) as u32) } } @@ -122,6 +209,31 @@ impl mach_msg_type_descriptor_t { } } #[inline] + pub unsafe fn type__raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 24usize, 8u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_type_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 24usize, + 8u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( pad3: ::std::os::raw::c_uint, type_: ::std::os::raw::c_uint, diff --git a/bindgen-tests/tests/expectations/tests/bitfield_pack_offset.rs b/bindgen-tests/tests/expectations/tests/bitfield_pack_offset.rs new file mode 100644 index 0000000000..d654e25b27 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bitfield_pack_offset.rs @@ -0,0 +1,507 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit { + storage: Storage, +} +impl __BindgenBitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage } + } +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + fn extract_bit(byte: u8, index: usize) -> bool { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct A { + pub name: [::std::os::raw::c_uchar; 7usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, + pub maxYield: ::std::os::raw::c_uchar, + pub _bitfield_2: __BindgenBitfieldUnit<[u8; 1usize]>, + pub description1: *const ::std::os::raw::c_uchar, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::() - 24usize]; + ["Alignment of A"][::std::mem::align_of::() - 8usize]; + ["Offset of field: A::name"][::std::mem::offset_of!(A, name) - 0usize]; + ["Offset of field: A::maxYield"][::std::mem::offset_of!(A, maxYield) - 10usize]; + [ + "Offset of field: A::description1", + ][::std::mem::offset_of!(A, description1) - 16usize]; +}; +impl Default for A { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl A { + #[inline] + pub fn firmness(&self) -> ::std::os::raw::c_uchar { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u8) } + } + #[inline] + pub fn set_firmness(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 4u8, val as u64) + } + } + #[inline] + pub unsafe fn firmness_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 4u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_firmness_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 4u8, + val as u64, + ) + } + } + #[inline] + pub fn color(&self) -> ::std::os::raw::c_uchar { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u8) } + } + #[inline] + pub fn set_color(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 4u8, val as u64) + } + } + #[inline] + pub unsafe fn color_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 4u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_color_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 4usize, + 4u8, + val as u64, + ) + } + } + #[inline] + pub fn weedsBonus(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 3u8) as u16) } + } + #[inline] + pub fn set_weedsBonus(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 3u8, val as u64) + } + } + #[inline] + pub unsafe fn weedsBonus_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 8usize, 3u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_weedsBonus_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 8usize, + 3u8, + val as u64, + ) + } + } + #[inline] + pub fn pestsBonus(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 3u8) as u16) } + } + #[inline] + pub fn set_pestsBonus(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 3u8, val as u64) + } + } + #[inline] + pub unsafe fn pestsBonus_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 11usize, 3u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_pestsBonus_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 11usize, + 3u8, + val as u64, + ) + } + } + #[inline] + pub fn size(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 10u8) as u16) } + } + #[inline] + pub fn set_size(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 10u8, val as u64) + } + } + #[inline] + pub unsafe fn size_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 14usize, 10u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_size_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 14usize, + 10u8, + val as u64, + ) + } + } + #[inline] + pub fn new_bitfield_1( + firmness: ::std::os::raw::c_uchar, + color: ::std::os::raw::c_uchar, + weedsBonus: ::std::os::raw::c_ushort, + pestsBonus: ::std::os::raw::c_ushort, + size: ::std::os::raw::c_ushort, + ) -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 4u8, + { + let firmness: u8 = unsafe { ::std::mem::transmute(firmness) }; + firmness as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 4usize, + 4u8, + { + let color: u8 = unsafe { ::std::mem::transmute(color) }; + color as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 8usize, + 3u8, + { + let weedsBonus: u16 = unsafe { ::std::mem::transmute(weedsBonus) }; + weedsBonus as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 11usize, + 3u8, + { + let pestsBonus: u16 = unsafe { ::std::mem::transmute(pestsBonus) }; + pestsBonus as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 14usize, + 10u8, + { + let size: u16 = unsafe { ::std::mem::transmute(size) }; + size as u64 + }, + ); + __bindgen_bitfield_unit + } + #[inline] + pub fn minYield(&self) -> ::std::os::raw::c_uchar { + unsafe { ::std::mem::transmute(self._bitfield_2.get(0usize, 4u8) as u8) } + } + #[inline] + pub fn set_minYield(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(0usize, 4u8, val as u64) + } + } + #[inline] + pub unsafe fn minYield_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 0usize, 4u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_minYield_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 0usize, + 4u8, + val as u64, + ) + } + } + #[inline] + pub fn waterBonus(&self) -> ::std::os::raw::c_uchar { + unsafe { ::std::mem::transmute(self._bitfield_2.get(4usize, 4u8) as u8) } + } + #[inline] + pub fn set_waterBonus(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(4usize, 4u8, val as u64) + } + } + #[inline] + pub unsafe fn waterBonus_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 4usize, 4u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_waterBonus_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 4usize, + 4u8, + val as u64, + ) + } + } + #[inline] + pub fn new_bitfield_2( + minYield: ::std::os::raw::c_uchar, + waterBonus: ::std::os::raw::c_uchar, + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 4u8, + { + let minYield: u8 = unsafe { ::std::mem::transmute(minYield) }; + minYield as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 4usize, + 4u8, + { + let waterBonus: u8 = unsafe { ::std::mem::transmute(waterBonus) }; + waterBonus as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs index 60cf6b8056..6f9adcb5ab 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,11 +126,28 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Struct { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -107,6 +168,30 @@ impl Struct { } } #[inline] + pub unsafe fn a_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_a_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b(&self) -> ::std::os::raw::c_uchar { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } } @@ -118,6 +203,30 @@ impl Struct { } } #[inline] + pub unsafe fn b_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn c(&self) -> ::std::os::raw::c_uchar { unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 6u8) as u8) } } @@ -129,6 +238,30 @@ impl Struct { } } #[inline] + pub unsafe fn c_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 6u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_c_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 2usize, + 6u8, + val as u64, + ) + } + } + #[inline] pub fn d(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 16u8) as u16) } } @@ -140,6 +273,31 @@ impl Struct { } } #[inline] + pub unsafe fn d_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 8usize, 16u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_d_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 8usize, + 16u8, + val as u64, + ) + } + } + #[inline] pub fn e(&self) -> ::std::os::raw::c_uchar { unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 8u8) as u8) } } @@ -151,6 +309,31 @@ impl Struct { } } #[inline] + pub unsafe fn e_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 24usize, 8u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_e_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 24usize, + 8u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( a: ::std::os::raw::c_uchar, b: ::std::os::raw::c_uchar, @@ -210,7 +393,7 @@ impl Struct { #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Inner { - pub _bitfield_align_1: [u16; 0], + pub _bindgen_align: [u16; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -231,6 +414,31 @@ impl Inner { } } #[inline] + pub unsafe fn a_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 16u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_a_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 16u8, + val as u64, + ) + } + } + #[inline] pub fn b(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 16u8) as u16) } } @@ -242,6 +450,31 @@ impl Inner { } } #[inline] + pub unsafe fn b_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 16usize, 16u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 16usize, + 16u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( a: ::std::os::raw::c_ushort, b: ::std::os::raw::c_ushort, diff --git a/bindgen-tests/tests/expectations/tests/block_return_type.rs b/bindgen-tests/tests/expectations/tests/block_return_type.rs index fa6c0ac67c..8ab2d70f11 100644 --- a/bindgen-tests/tests/expectations/tests/block_return_type.rs +++ b/bindgen-tests/tests/expectations/tests/block_return_type.rs @@ -1,7 +1,7 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #![cfg(target_os = "macos")] extern crate block; -extern "C" { +unsafe extern "C" { pub fn func() -> _bindgen_ty_id_4; } pub type _bindgen_ty_id_4 = *const ::block::Block< diff --git a/bindgen-tests/tests/expectations/tests/blocklist-function.rs b/bindgen-tests/tests/expectations/tests/blocklist-function.rs index 2e12a01e9e..65b66b2ac2 100644 --- a/bindgen-tests/tests/expectations/tests/blocklist-function.rs +++ b/bindgen-tests/tests/expectations/tests/blocklist-function.rs @@ -10,7 +10,7 @@ pub mod root { pub mod bar { #[allow(unused_imports)] use self::super::super::root; - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN3bar18NamespacedFunctionEv"] pub fn NamespacedFunction(); } diff --git a/bindgen-tests/tests/expectations/tests/blocklist-item.rs b/bindgen-tests/tests/expectations/tests/blocklist-item.rs index 39de8002b3..c5daf050a1 100644 --- a/bindgen-tests/tests/expectations/tests/blocklist-item.rs +++ b/bindgen-tests/tests/expectations/tests/blocklist-item.rs @@ -10,7 +10,7 @@ pub mod root { pub mod bar { #[allow(unused_imports)] use self::super::super::root; - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN3bar18NamespacedFunctionEv"] pub fn NamespacedFunction(); } diff --git a/bindgen-tests/tests/expectations/tests/blocklist-methods.rs b/bindgen-tests/tests/expectations/tests/blocklist-methods.rs index 37bb95492d..c89cadb3d5 100644 --- a/bindgen-tests/tests/expectations/tests/blocklist-methods.rs +++ b/bindgen-tests/tests/expectations/tests/blocklist-methods.rs @@ -9,7 +9,7 @@ const _: () = { ["Size of Foo"][::std::mem::size_of::() - 1usize]; ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo3fooEv"] pub fn Foo_foo(this: *mut Foo) -> ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/blocklist_bitfield_unit.rs b/bindgen-tests/tests/expectations/tests/blocklist_bitfield_unit.rs index b5737a8d99..77c263e3cc 100644 --- a/bindgen-tests/tests/expectations/tests/blocklist_bitfield_unit.rs +++ b/bindgen-tests/tests/expectations/tests/blocklist_bitfield_unit.rs @@ -6,7 +6,6 @@ use bitfields::*; #[derive(Debug, Default, Copy, Clone)] pub struct C { pub x: ::std::os::raw::c_uchar, - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub baz: ::std::os::raw::c_uint, } @@ -30,6 +29,31 @@ impl C { } } #[inline] + pub unsafe fn b1_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b1_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b2(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } } @@ -41,6 +65,31 @@ impl C { } } #[inline] + pub unsafe fn b2_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b2_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( b1: ::std::os::raw::c_uint, b2: ::std::os::raw::c_uint, diff --git a/bindgen-tests/tests/expectations/tests/blocks-signature.rs b/bindgen-tests/tests/expectations/tests/blocks-signature.rs index b1615839ca..93cf28e009 100644 --- a/bindgen-tests/tests/expectations/tests/blocks-signature.rs +++ b/bindgen-tests/tests/expectations/tests/blocks-signature.rs @@ -1,24 +1,24 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #![cfg(target_os = "macos")] extern crate block; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z8atexit_bU13block_pointerFvvE"] pub fn atexit_b(arg1: _bindgen_ty_id_33); } pub type dispatch_data_t = *mut ::std::os::raw::c_void; pub type dispatch_data_applier_t = _bindgen_ty_id_40; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z19dispatch_data_applyPvU13block_pointerFbS_yPKvyE"] pub fn dispatch_data_apply( data: dispatch_data_t, applier: dispatch_data_applier_t, ) -> bool; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z3fooU13block_pointerFvyE"] pub fn foo(arg1: _bindgen_ty_id_50) -> bool; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z7foo_ptrPU13block_pointerFvyE"] pub fn foo_ptr(arg1: *mut _bindgen_ty_id_56) -> bool; } diff --git a/bindgen-tests/tests/expectations/tests/blocks.rs b/bindgen-tests/tests/expectations/tests/blocks.rs index ea15d22464..4f51113c4b 100644 --- a/bindgen-tests/tests/expectations/tests/blocks.rs +++ b/bindgen-tests/tests/expectations/tests/blocks.rs @@ -1,23 +1,23 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #![cfg(target_os = "macos")] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z8atexit_bU13block_pointerFvvE"] pub fn atexit_b(arg1: *mut ::std::os::raw::c_void); } pub type dispatch_data_t = *mut ::std::os::raw::c_void; pub type dispatch_data_applier_t = *mut ::std::os::raw::c_void; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z19dispatch_data_applyPvU13block_pointerFbS_yPKvyE"] pub fn dispatch_data_apply( data: dispatch_data_t, applier: dispatch_data_applier_t, ) -> bool; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z3fooU13block_pointerFvyE"] pub fn foo(arg1: *mut ::std::os::raw::c_void) -> bool; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z7foo_ptrPU13block_pointerFvyE"] pub fn foo_ptr(arg1: *mut *mut ::std::os::raw::c_void) -> bool; } diff --git a/bindgen-tests/tests/expectations/tests/c-unwind-abi-override.rs b/bindgen-tests/tests/expectations/tests/c-unwind-abi-override.rs index 25fd333cea..a158565033 100644 --- a/bindgen-tests/tests/expectations/tests/c-unwind-abi-override.rs +++ b/bindgen-tests/tests/expectations/tests/c-unwind-abi-override.rs @@ -1,10 +1,10 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C-unwind" { +unsafe extern "C-unwind" { pub fn foo(); } -extern "C-unwind" { +unsafe extern "C-unwind" { pub fn bar(); } -extern "C" { +unsafe extern "C" { pub fn baz(); } diff --git a/bindgen-tests/tests/expectations/tests/c_naming.rs b/bindgen-tests/tests/expectations/tests/c_naming.rs index 502c4486eb..38e63ce874 100644 --- a/bindgen-tests/tests/expectations/tests/c_naming.rs +++ b/bindgen-tests/tests/expectations/tests/c_naming.rs @@ -36,12 +36,12 @@ impl Default for union_b { pub type b = union_b; pub const enum_c_A: enum_c = 0; pub type enum_c = ::std::os::raw::c_uint; -extern "C" { +unsafe extern "C" { pub fn takes_a(arg: a); } -extern "C" { +unsafe extern "C" { pub fn takes_b(arg: b); } -extern "C" { +unsafe extern "C" { pub fn takes_c(arg: enum_c); } diff --git a/bindgen-tests/tests/expectations/tests/call-conv-field.rs b/bindgen-tests/tests/expectations/tests/call-conv-field.rs index 089b34b134..8f0502a435 100644 --- a/bindgen-tests/tests/expectations/tests/call-conv-field.rs +++ b/bindgen-tests/tests/expectations/tests/call-conv-field.rs @@ -25,6 +25,6 @@ const _: () = { "Offset of field: JNINativeInterface_::__hack", ][::std::mem::offset_of!(JNINativeInterface_, __hack) - 8usize]; }; -extern "stdcall" { +unsafe extern "stdcall" { pub fn bar(); } diff --git a/bindgen-tests/tests/expectations/tests/canonical_path_without_namespacing.rs b/bindgen-tests/tests/expectations/tests/canonical_path_without_namespacing.rs index d07751a8db..613da3060f 100644 --- a/bindgen-tests/tests/expectations/tests/canonical_path_without_namespacing.rs +++ b/bindgen-tests/tests/expectations/tests/canonical_path_without_namespacing.rs @@ -9,7 +9,7 @@ const _: () = { ["Size of Bar"][::std::mem::size_of::() - 1usize]; ["Alignment of Bar"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z3bazPN3foo3BarE"] pub fn baz(arg1: *mut Bar); } diff --git a/bindgen-tests/tests/expectations/tests/char16_t.rs b/bindgen-tests/tests/expectations/tests/char16_t.rs new file mode 100644 index 0000000000..82d30fe517 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/char16_t.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(transparent)] +pub struct bindgen_cchar16_t(u16); +unsafe extern "C" { + #[link_name = "\u{1}_Z16receive_char16_tDs"] + pub fn receive_char16_t(input: bindgen_cchar16_t); +} diff --git a/bindgen-tests/tests/expectations/tests/class.rs b/bindgen-tests/tests/expectations/tests/class.rs index 69591d1bce..98ee43b374 100644 --- a/bindgen-tests/tests/expectations/tests/class.rs +++ b/bindgen-tests/tests/expectations/tests/class.rs @@ -30,28 +30,18 @@ impl ::std::fmt::Debug for __IncompleteArrayField { } } #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] pub struct C { pub a: ::std::os::raw::c_int, pub big_array: [::std::os::raw::c_char; 33usize], } -#[test] -fn bindgen_test_layout_C() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 40usize, "Size of C"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of C"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: C::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).big_array) as usize - ptr as usize }, - 4usize, - "Offset of field: C::big_array", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 40usize]; + ["Alignment of C"][::std::mem::align_of::() - 4usize]; + ["Offset of field: C::a"][::std::mem::offset_of!(C, a) - 0usize]; + ["Offset of field: C::big_array"][::std::mem::offset_of!(C, big_array) - 4usize]; +}; impl Default for C { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -62,43 +52,30 @@ impl Default for C { } } #[repr(C)] +#[derive(Debug)] pub struct C_with_zero_length_array { pub a: ::std::os::raw::c_int, pub big_array: [::std::os::raw::c_char; 33usize], pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, } -#[test] -fn bindgen_test_layout_C_with_zero_length_array() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 40usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of C_with_zero_length_array", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 40usize]; + [ "Alignment of C_with_zero_length_array", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: C_with_zero_length_array::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).big_array) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(C_with_zero_length_array, a) - 0usize]; + [ "Offset of field: C_with_zero_length_array::big_array", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).zero_length_array) as usize - ptr as usize - }, - 37usize, + ][::std::mem::offset_of!(C_with_zero_length_array, big_array) - 4usize]; + [ "Offset of field: C_with_zero_length_array::zero_length_array", - ); -} + ][::std::mem::offset_of!(C_with_zero_length_array, zero_length_array) - 37usize]; +}; impl Default for C_with_zero_length_array { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -114,69 +91,46 @@ pub struct C_with_zero_length_array_2 { pub a: ::std::os::raw::c_int, pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, } -#[test] -fn bindgen_test_layout_C_with_zero_length_array_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of C_with_zero_length_array_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 4usize]; + [ "Alignment of C_with_zero_length_array_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: C_with_zero_length_array_2::a", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).zero_length_array) as usize - ptr as usize - }, - 4usize, + ][::std::mem::offset_of!(C_with_zero_length_array_2, a) - 0usize]; + [ "Offset of field: C_with_zero_length_array_2::zero_length_array", - ); -} + ][::std::mem::offset_of!(C_with_zero_length_array_2, zero_length_array) - 4usize]; +}; #[repr(C)] +#[derive(Debug)] pub struct C_with_incomplete_array { pub a: ::std::os::raw::c_int, pub big_array: [::std::os::raw::c_char; 33usize], pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, } -#[test] -fn bindgen_test_layout_C_with_incomplete_array() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 40usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of C_with_incomplete_array", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 40usize]; + [ "Alignment of C_with_incomplete_array", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: C_with_incomplete_array::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).big_array) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(C_with_incomplete_array, a) - 0usize]; + [ "Offset of field: C_with_incomplete_array::big_array", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).incomplete_array) as usize - ptr as usize }, - 37usize, + ][::std::mem::offset_of!(C_with_incomplete_array, big_array) - 4usize]; + [ "Offset of field: C_with_incomplete_array::incomplete_array", - ); -} + ][::std::mem::offset_of!(C_with_incomplete_array, incomplete_array) - 37usize]; +}; impl Default for C_with_incomplete_array { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -192,77 +146,55 @@ pub struct C_with_incomplete_array_2 { pub a: ::std::os::raw::c_int, pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, } -#[test] -fn bindgen_test_layout_C_with_incomplete_array_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of C_with_incomplete_array_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 4usize]; + [ "Alignment of C_with_incomplete_array_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: C_with_incomplete_array_2::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).incomplete_array) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(C_with_incomplete_array_2, a) - 0usize]; + [ "Offset of field: C_with_incomplete_array_2::incomplete_array", - ); -} + ][::std::mem::offset_of!(C_with_incomplete_array_2, incomplete_array) - 4usize]; +}; #[repr(C)] +#[derive(Debug)] pub struct C_with_zero_length_array_and_incomplete_array { pub a: ::std::os::raw::c_int, pub big_array: [::std::os::raw::c_char; 33usize], pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, } -#[test] -fn bindgen_test_layout_C_with_zero_length_array_and_incomplete_array() { - const UNINIT: ::std::mem::MaybeUninit< - C_with_zero_length_array_and_incomplete_array, - > = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 40usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of C_with_zero_length_array_and_incomplete_array", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 40usize]; + [ "Alignment of C_with_zero_length_array_and_incomplete_array", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: C_with_zero_length_array_and_incomplete_array::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).big_array) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(C_with_zero_length_array_and_incomplete_array, a) - 0usize]; + [ "Offset of field: C_with_zero_length_array_and_incomplete_array::big_array", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).zero_length_array) as usize - ptr as usize - }, - 37usize, + ][::std::mem::offset_of!(C_with_zero_length_array_and_incomplete_array, big_array) + - 4usize]; + [ "Offset of field: C_with_zero_length_array_and_incomplete_array::zero_length_array", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).incomplete_array) as usize - ptr as usize }, - 37usize, + ][::std::mem::offset_of!( + C_with_zero_length_array_and_incomplete_array, zero_length_array + ) - 37usize]; + [ "Offset of field: C_with_zero_length_array_and_incomplete_array::incomplete_array", - ); -} + ][::std::mem::offset_of!( + C_with_zero_length_array_and_incomplete_array, incomplete_array + ) - 37usize]; +}; impl Default for C_with_zero_length_array_and_incomplete_array { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -279,87 +211,62 @@ pub struct C_with_zero_length_array_and_incomplete_array_2 { pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, } -#[test] -fn bindgen_test_layout_C_with_zero_length_array_and_incomplete_array_2() { - const UNINIT: ::std::mem::MaybeUninit< - C_with_zero_length_array_and_incomplete_array_2, - > = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of C_with_zero_length_array_and_incomplete_array_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 4usize]; + [ "Alignment of C_with_zero_length_array_and_incomplete_array_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() + - 4usize]; + [ "Offset of field: C_with_zero_length_array_and_incomplete_array_2::a", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).zero_length_array) as usize - ptr as usize - }, - 4usize, + ][::std::mem::offset_of!(C_with_zero_length_array_and_incomplete_array_2, a) + - 0usize]; + [ "Offset of field: C_with_zero_length_array_and_incomplete_array_2::zero_length_array", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).incomplete_array) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!( + C_with_zero_length_array_and_incomplete_array_2, zero_length_array + ) - 4usize]; + [ "Offset of field: C_with_zero_length_array_and_incomplete_array_2::incomplete_array", - ); -} + ][::std::mem::offset_of!( + C_with_zero_length_array_and_incomplete_array_2, incomplete_array + ) - 4usize]; +}; #[repr(C)] #[derive(Debug, Default, Hash, PartialOrd, Ord, PartialEq, Eq)] pub struct WithDtor { pub b: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_WithDtor() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of WithDtor"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of WithDtor"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: WithDtor::b", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of WithDtor"][::std::mem::size_of::() - 4usize]; + ["Alignment of WithDtor"][::std::mem::align_of::() - 4usize]; + ["Offset of field: WithDtor::b"][::std::mem::offset_of!(WithDtor, b) - 0usize]; +}; #[repr(C)] +#[derive(Debug)] pub struct IncompleteArrayNonCopiable { pub whatever: *mut ::std::os::raw::c_void, pub incomplete_array: __IncompleteArrayField, } -#[test] -fn bindgen_test_layout_IncompleteArrayNonCopiable() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of IncompleteArrayNonCopiable", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, + ][::std::mem::size_of::() - 8usize]; + [ "Alignment of IncompleteArrayNonCopiable", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).whatever) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 8usize]; + [ "Offset of field: IncompleteArrayNonCopiable::whatever", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).incomplete_array) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(IncompleteArrayNonCopiable, whatever) - 0usize]; + [ "Offset of field: IncompleteArrayNonCopiable::incomplete_array", - ); -} + ][::std::mem::offset_of!(IncompleteArrayNonCopiable, incomplete_array) - 8usize]; +}; impl Default for IncompleteArrayNonCopiable { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -375,23 +282,13 @@ pub union Union { pub d: f32, pub i: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_Union() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of Union"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of Union"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).d) as usize - ptr as usize }, - 0usize, - "Offset of field: Union::d", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).i) as usize - ptr as usize }, - 0usize, - "Offset of field: Union::i", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Union"][::std::mem::size_of::() - 4usize]; + ["Alignment of Union"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Union::d"][::std::mem::offset_of!(Union, d) - 0usize]; + ["Offset of field: Union::i"][::std::mem::offset_of!(Union, i) - 0usize]; +}; impl Default for Union { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -406,18 +303,14 @@ impl Default for Union { pub struct WithUnion { pub data: Union, } -#[test] -fn bindgen_test_layout_WithUnion() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of WithUnion"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of WithUnion"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).data) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of WithUnion"][::std::mem::size_of::() - 4usize]; + ["Alignment of WithUnion"][::std::mem::align_of::() - 4usize]; + [ "Offset of field: WithUnion::data", - ); -} + ][::std::mem::offset_of!(WithUnion, data) - 0usize]; +}; impl Default for WithUnion { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -432,39 +325,35 @@ impl Default for WithUnion { pub struct RealAbstractionWithTonsOfMethods { pub _address: u8, } -#[test] -fn bindgen_test_layout_RealAbstractionWithTonsOfMethods() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of RealAbstractionWithTonsOfMethods", - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, + ][::std::mem::size_of::() - 1usize]; + [ "Alignment of RealAbstractionWithTonsOfMethods", - ); -} -extern "C" { + ][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { #[link_name = "\u{1}_ZNK32RealAbstractionWithTonsOfMethods3barEv"] pub fn RealAbstractionWithTonsOfMethods_bar( this: *const RealAbstractionWithTonsOfMethods, ); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3barEv"] pub fn RealAbstractionWithTonsOfMethods_bar1( this: *mut RealAbstractionWithTonsOfMethods, ); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3barEi"] pub fn RealAbstractionWithTonsOfMethods_bar2( this: *mut RealAbstractionWithTonsOfMethods, foo: ::std::os::raw::c_int, ); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3staEv"] pub fn RealAbstractionWithTonsOfMethods_sta(); } diff --git a/bindgen-tests/tests/expectations/tests/class_1_0.rs b/bindgen-tests/tests/expectations/tests/class_1_0.rs deleted file mode 100644 index 9db5b3a338..0000000000 --- a/bindgen-tests/tests/expectations/tests/class_1_0.rs +++ /dev/null @@ -1,539 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -#[derive(Default)] -pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); -impl __IncompleteArrayField { - #[inline] - pub fn new() -> Self { - __IncompleteArrayField(::std::marker::PhantomData, []) - } - #[inline] - pub fn as_ptr(&self) -> *const T { - self as *const _ as *const T - } - #[inline] - pub fn as_mut_ptr(&mut self) -> *mut T { - self as *mut _ as *mut T - } - #[inline] - pub unsafe fn as_slice(&self, len: usize) -> &[T] { - ::std::slice::from_raw_parts(self.as_ptr(), len) - } - #[inline] - pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { - ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) - } -} -impl ::std::fmt::Debug for __IncompleteArrayField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__IncompleteArrayField") - } -} -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Copy)] -pub struct C { - pub a: ::std::os::raw::c_int, - pub big_array: [::std::os::raw::c_char; 33usize], -} -#[test] -fn bindgen_test_layout_C() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 40usize, "Size of C"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of C"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: C::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).big_array) as usize - ptr as usize }, - 4usize, - "Offset of field: C::big_array", - ); -} -impl Clone for C { - fn clone(&self) -> Self { - *self - } -} -impl Default for C { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -impl ::std::cmp::PartialEq for C { - fn eq(&self, other: &C) -> bool { - self.a == other.a && &self.big_array[..] == &other.big_array[..] - } -} -#[repr(C)] -pub struct C_with_zero_length_array { - pub a: ::std::os::raw::c_int, - pub big_array: [::std::os::raw::c_char; 33usize], - pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_C_with_zero_length_array() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 40usize, - "Size of C_with_zero_length_array", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of C_with_zero_length_array", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: C_with_zero_length_array::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).big_array) as usize - ptr as usize }, - 4usize, - "Offset of field: C_with_zero_length_array::big_array", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).zero_length_array) as usize - ptr as usize - }, - 37usize, - "Offset of field: C_with_zero_length_array::zero_length_array", - ); -} -impl Default for C_with_zero_length_array { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Default)] -pub struct C_with_zero_length_array_2 { - pub a: ::std::os::raw::c_int, - pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_C_with_zero_length_array_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of C_with_zero_length_array_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of C_with_zero_length_array_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: C_with_zero_length_array_2::a", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).zero_length_array) as usize - ptr as usize - }, - 4usize, - "Offset of field: C_with_zero_length_array_2::zero_length_array", - ); -} -#[repr(C)] -pub struct C_with_incomplete_array { - pub a: ::std::os::raw::c_int, - pub big_array: [::std::os::raw::c_char; 33usize], - pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_C_with_incomplete_array() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 40usize, - "Size of C_with_incomplete_array", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of C_with_incomplete_array", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: C_with_incomplete_array::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).big_array) as usize - ptr as usize }, - 4usize, - "Offset of field: C_with_incomplete_array::big_array", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).incomplete_array) as usize - ptr as usize }, - 37usize, - "Offset of field: C_with_incomplete_array::incomplete_array", - ); -} -impl Default for C_with_incomplete_array { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Default)] -pub struct C_with_incomplete_array_2 { - pub a: ::std::os::raw::c_int, - pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_C_with_incomplete_array_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of C_with_incomplete_array_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of C_with_incomplete_array_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: C_with_incomplete_array_2::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).incomplete_array) as usize - ptr as usize }, - 4usize, - "Offset of field: C_with_incomplete_array_2::incomplete_array", - ); -} -#[repr(C)] -pub struct C_with_zero_length_array_and_incomplete_array { - pub a: ::std::os::raw::c_int, - pub big_array: [::std::os::raw::c_char; 33usize], - pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, - pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_C_with_zero_length_array_and_incomplete_array() { - const UNINIT: ::std::mem::MaybeUninit< - C_with_zero_length_array_and_incomplete_array, - > = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 40usize, - "Size of C_with_zero_length_array_and_incomplete_array", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of C_with_zero_length_array_and_incomplete_array", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: C_with_zero_length_array_and_incomplete_array::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).big_array) as usize - ptr as usize }, - 4usize, - "Offset of field: C_with_zero_length_array_and_incomplete_array::big_array", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).zero_length_array) as usize - ptr as usize - }, - 37usize, - "Offset of field: C_with_zero_length_array_and_incomplete_array::zero_length_array", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).incomplete_array) as usize - ptr as usize }, - 37usize, - "Offset of field: C_with_zero_length_array_and_incomplete_array::incomplete_array", - ); -} -impl Default for C_with_zero_length_array_and_incomplete_array { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Default)] -pub struct C_with_zero_length_array_and_incomplete_array_2 { - pub a: ::std::os::raw::c_int, - pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>, - pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>, -} -#[test] -fn bindgen_test_layout_C_with_zero_length_array_and_incomplete_array_2() { - const UNINIT: ::std::mem::MaybeUninit< - C_with_zero_length_array_and_incomplete_array_2, - > = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of C_with_zero_length_array_and_incomplete_array_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of C_with_zero_length_array_and_incomplete_array_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: C_with_zero_length_array_and_incomplete_array_2::a", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).zero_length_array) as usize - ptr as usize - }, - 4usize, - "Offset of field: C_with_zero_length_array_and_incomplete_array_2::zero_length_array", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).incomplete_array) as usize - ptr as usize }, - 4usize, - "Offset of field: C_with_zero_length_array_and_incomplete_array_2::incomplete_array", - ); -} -#[repr(C)] -#[derive(Debug, Default, Hash, PartialEq, Eq)] -pub struct WithDtor { - pub b: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_WithDtor() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of WithDtor"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of WithDtor"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: WithDtor::b", - ); -} -#[repr(C)] -pub struct IncompleteArrayNonCopiable { - pub whatever: *mut ::std::os::raw::c_void, - pub incomplete_array: __IncompleteArrayField, -} -#[test] -fn bindgen_test_layout_IncompleteArrayNonCopiable() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of IncompleteArrayNonCopiable", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of IncompleteArrayNonCopiable", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).whatever) as usize - ptr as usize }, - 0usize, - "Offset of field: IncompleteArrayNonCopiable::whatever", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).incomplete_array) as usize - ptr as usize }, - 8usize, - "Offset of field: IncompleteArrayNonCopiable::incomplete_array", - ); -} -impl Default for IncompleteArrayNonCopiable { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq)] -pub struct Union { - pub d: __BindgenUnionField, - pub i: __BindgenUnionField<::std::os::raw::c_int>, - pub bindgen_union_field: u32, -} -#[test] -fn bindgen_test_layout_Union() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of Union"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of Union"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).d) as usize - ptr as usize }, - 0usize, - "Offset of field: Union::d", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).i) as usize - ptr as usize }, - 0usize, - "Offset of field: Union::i", - ); -} -impl Clone for Union { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq)] -pub struct WithUnion { - pub data: Union, -} -#[test] -fn bindgen_test_layout_WithUnion() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of WithUnion"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of WithUnion"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).data) as usize - ptr as usize }, - 0usize, - "Offset of field: WithUnion::data", - ); -} -impl Clone for WithUnion { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct RealAbstractionWithTonsOfMethods { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_RealAbstractionWithTonsOfMethods() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - "Size of RealAbstractionWithTonsOfMethods", - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - "Alignment of RealAbstractionWithTonsOfMethods", - ); -} -extern "C" { - #[link_name = "\u{1}_ZNK32RealAbstractionWithTonsOfMethods3barEv"] - pub fn RealAbstractionWithTonsOfMethods_bar( - this: *const RealAbstractionWithTonsOfMethods, - ); -} -extern "C" { - #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3barEv"] - pub fn RealAbstractionWithTonsOfMethods_bar1( - this: *mut RealAbstractionWithTonsOfMethods, - ); -} -extern "C" { - #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3barEi"] - pub fn RealAbstractionWithTonsOfMethods_bar2( - this: *mut RealAbstractionWithTonsOfMethods, - foo: ::std::os::raw::c_int, - ); -} -extern "C" { - #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3staEv"] - pub fn RealAbstractionWithTonsOfMethods_sta(); -} -impl Clone for RealAbstractionWithTonsOfMethods { - fn clone(&self) -> Self { - *self - } -} -impl RealAbstractionWithTonsOfMethods { - #[inline] - pub unsafe fn bar(&self) { - RealAbstractionWithTonsOfMethods_bar(self) - } - #[inline] - pub unsafe fn bar1(&mut self) { - RealAbstractionWithTonsOfMethods_bar1(self) - } - #[inline] - pub unsafe fn bar2(&mut self, foo: ::std::os::raw::c_int) { - RealAbstractionWithTonsOfMethods_bar2(self, foo) - } - #[inline] - pub unsafe fn sta() { - RealAbstractionWithTonsOfMethods_sta() - } -} diff --git a/bindgen-tests/tests/expectations/tests/class_nested.rs b/bindgen-tests/tests/expectations/tests/class_nested.rs index 881a95fd93..080f5968bc 100644 --- a/bindgen-tests/tests/expectations/tests/class_nested.rs +++ b/bindgen-tests/tests/expectations/tests/class_nested.rs @@ -47,7 +47,7 @@ const _: () = { ["Alignment of A_C"][::std::mem::align_of::() - 4usize]; ["Offset of field: A_C::baz"][::std::mem::offset_of!(A_C, baz) - 0usize]; }; -extern "C" { +unsafe extern "C" { pub static mut var: A_B; } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -59,7 +59,7 @@ const _: () = { "Align of template specialization: A_D_open0_int_close0", ][::std::mem::align_of::>() - 4usize]; }; -extern "C" { +unsafe extern "C" { pub static mut baz: A_D<::std::os::raw::c_int>; } #[repr(C)] diff --git a/bindgen-tests/tests/expectations/tests/class_static.rs b/bindgen-tests/tests/expectations/tests/class_static.rs index c93968fa0c..d448165d62 100644 --- a/bindgen-tests/tests/expectations/tests/class_static.rs +++ b/bindgen-tests/tests/expectations/tests/class_static.rs @@ -4,11 +4,11 @@ pub struct MyClass { pub _address: u8, } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN7MyClass7exampleE"] pub static mut MyClass_example: *const ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN7MyClass26example_check_no_collisionE"] pub static mut MyClass_example_check_no_collision: *const ::std::os::raw::c_int; } @@ -17,7 +17,7 @@ const _: () = { ["Size of MyClass"][::std::mem::size_of::() - 1usize]; ["Alignment of MyClass"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZL26example_check_no_collision"] pub static mut example_check_no_collision: *const ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/class_with_enum.rs b/bindgen-tests/tests/expectations/tests/class_with_enum.rs new file mode 100644 index 0000000000..ca1806357c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/class_with_enum.rs @@ -0,0 +1,14 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct A { + pub _address: u8, +} +pub const A_B_B1: A_B = 0; +pub const A_B_B2: A_B = 1; +pub type A_B = ::std::os::raw::c_uint; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::() - 1usize]; + ["Alignment of A"][::std::mem::align_of::() - 1usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/class_with_inner_struct_1_0.rs b/bindgen-tests/tests/expectations/tests/class_with_inner_struct_1_0.rs deleted file mode 100644 index 23afad6319..0000000000 --- a/bindgen-tests/tests/expectations/tests/class_with_inner_struct_1_0.rs +++ /dev/null @@ -1,397 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct A { - pub c: ::std::os::raw::c_uint, - pub named_union: A__bindgen_ty_1, - pub __bindgen_anon_1: A__bindgen_ty_2, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct A_Segment { - pub begin: ::std::os::raw::c_int, - pub end: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_A_Segment() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of A_Segment"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of A_Segment"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).begin) as usize - ptr as usize }, - 0usize, - "Offset of field: A_Segment::begin", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).end) as usize - ptr as usize }, - 4usize, - "Offset of field: A_Segment::end", - ); -} -impl Clone for A_Segment { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct A__bindgen_ty_1 { - pub f: __BindgenUnionField<::std::os::raw::c_int>, - pub bindgen_union_field: u32, -} -#[test] -fn bindgen_test_layout_A__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of A__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of A__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).f) as usize - ptr as usize }, - 0usize, - "Offset of field: A__bindgen_ty_1::f", - ); -} -impl Clone for A__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct A__bindgen_ty_2 { - pub d: __BindgenUnionField<::std::os::raw::c_int>, - pub bindgen_union_field: u32, -} -#[test] -fn bindgen_test_layout_A__bindgen_ty_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of A__bindgen_ty_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of A__bindgen_ty_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).d) as usize - ptr as usize }, - 0usize, - "Offset of field: A__bindgen_ty_2::d", - ); -} -impl Clone for A__bindgen_ty_2 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_A() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 12usize, "Size of A"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of A"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).c) as usize - ptr as usize }, - 0usize, - "Offset of field: A::c", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).named_union) as usize - ptr as usize }, - 4usize, - "Offset of field: A::named_union", - ); -} -impl Clone for A { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct B { - pub d: ::std::os::raw::c_uint, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct B_Segment { - pub begin: ::std::os::raw::c_int, - pub end: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_B_Segment() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of B_Segment"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of B_Segment"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).begin) as usize - ptr as usize }, - 0usize, - "Offset of field: B_Segment::begin", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).end) as usize - ptr as usize }, - 4usize, - "Offset of field: B_Segment::end", - ); -} -impl Clone for B_Segment { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_B() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of B"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of B"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).d) as usize - ptr as usize }, - 0usize, - "Offset of field: B::d", - ); -} -impl Clone for B { - fn clone(&self) -> Self { - *self - } -} -#[repr(i32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum StepSyntax { - Keyword = 0, - FunctionalWithoutKeyword = 1, - FunctionalWithStartKeyword = 2, - FunctionalWithEndKeyword = 3, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq)] -pub struct C { - pub d: ::std::os::raw::c_uint, - pub __bindgen_anon_1: C__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq)] -pub struct C__bindgen_ty_1 { - pub mFunc: __BindgenUnionField, - pub __bindgen_anon_1: __BindgenUnionField, - pub bindgen_union_field: [u32; 4usize], -} -#[repr(C)] -#[derive(Debug, Default, Copy, PartialEq)] -pub struct C__bindgen_ty_1__bindgen_ty_1 { - pub mX1: f32, - pub mY1: f32, - pub mX2: f32, - pub mY2: f32, -} -#[test] -fn bindgen_test_layout_C__bindgen_ty_1__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 16usize, - "Size of C__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of C__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mX1) as usize - ptr as usize }, - 0usize, - "Offset of field: C__bindgen_ty_1__bindgen_ty_1::mX1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mY1) as usize - ptr as usize }, - 4usize, - "Offset of field: C__bindgen_ty_1__bindgen_ty_1::mY1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mX2) as usize - ptr as usize }, - 8usize, - "Offset of field: C__bindgen_ty_1__bindgen_ty_1::mX2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mY2) as usize - ptr as usize }, - 12usize, - "Offset of field: C__bindgen_ty_1__bindgen_ty_1::mY2", - ); -} -impl Clone for C__bindgen_ty_1__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct C__bindgen_ty_1__bindgen_ty_2 { - pub mStepSyntax: StepSyntax, - pub mSteps: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_C__bindgen_ty_1__bindgen_ty_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of C__bindgen_ty_1__bindgen_ty_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of C__bindgen_ty_1__bindgen_ty_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mStepSyntax) as usize - ptr as usize }, - 0usize, - "Offset of field: C__bindgen_ty_1__bindgen_ty_2::mStepSyntax", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mSteps) as usize - ptr as usize }, - 4usize, - "Offset of field: C__bindgen_ty_1__bindgen_ty_2::mSteps", - ); -} -impl Clone for C__bindgen_ty_1__bindgen_ty_2 { - fn clone(&self) -> Self { - *self - } -} -impl Default for C__bindgen_ty_1__bindgen_ty_2 { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[test] -fn bindgen_test_layout_C__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 16usize, - "Size of C__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of C__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mFunc) as usize - ptr as usize }, - 0usize, - "Offset of field: C__bindgen_ty_1::mFunc", - ); -} -impl Clone for C__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct C_Segment { - pub begin: ::std::os::raw::c_int, - pub end: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_C_Segment() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of C_Segment"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of C_Segment"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).begin) as usize - ptr as usize }, - 0usize, - "Offset of field: C_Segment::begin", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).end) as usize - ptr as usize }, - 4usize, - "Offset of field: C_Segment::end", - ); -} -impl Clone for C_Segment { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_C() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 20usize, "Size of C"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of C"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).d) as usize - ptr as usize }, - 0usize, - "Offset of field: C::d", - ); -} -impl Clone for C { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/class_with_typedef.rs b/bindgen-tests/tests/expectations/tests/class_with_typedef.rs index 9a89732036..73f2b55cc3 100644 --- a/bindgen-tests/tests/expectations/tests/class_with_typedef.rs +++ b/bindgen-tests/tests/expectations/tests/class_with_typedef.rs @@ -21,19 +21,19 @@ const _: () = { ["Offset of field: C::d"][::std::mem::offset_of!(C, d) - 56usize]; ["Offset of field: C::other_ptr"][::std::mem::offset_of!(C, other_ptr) - 64usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1C6methodEi"] pub fn C_method(this: *mut C, c: C_MyInt); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1C9methodRefERi"] pub fn C_methodRef(this: *mut C, c: *mut C_MyInt); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1C16complexMethodRefERPKc"] pub fn C_complexMethodRef(this: *mut C, c: *mut C_Lookup); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1C13anotherMethodEi"] pub fn C_anotherMethod(this: *mut C, c: AnotherInt); } diff --git a/bindgen-tests/tests/expectations/tests/complex_global.rs b/bindgen-tests/tests/expectations/tests/complex_global.rs index 101ad0f49f..c818df676e 100644 --- a/bindgen-tests/tests/expectations/tests/complex_global.rs +++ b/bindgen-tests/tests/expectations/tests/complex_global.rs @@ -5,12 +5,12 @@ pub struct __BindgenComplex { pub re: T, pub im: T, } -extern "C" { +unsafe extern "C" { pub static mut globalValueFloat: __BindgenComplex; } -extern "C" { +unsafe extern "C" { pub static mut globalValueDouble: __BindgenComplex; } -extern "C" { +unsafe extern "C" { pub static mut globalValueLongDouble: __BindgenComplex; } diff --git a/bindgen-tests/tests/expectations/tests/const_array.rs b/bindgen-tests/tests/expectations/tests/const_array.rs index 8dae42d116..30852deb36 100644 --- a/bindgen-tests/tests/expectations/tests/const_array.rs +++ b/bindgen-tests/tests/expectations/tests/const_array.rs @@ -1,7 +1,7 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub static foo: [::std::os::raw::c_int; 1usize]; } -extern "C" { +unsafe extern "C" { pub static mut bar: [::std::os::raw::c_int; 1usize]; } diff --git a/bindgen-tests/tests/expectations/tests/const_array_fn_arg.rs b/bindgen-tests/tests/expectations/tests/const_array_fn_arg.rs index 035a56fa78..fb26311115 100644 --- a/bindgen-tests/tests/expectations/tests/const_array_fn_arg.rs +++ b/bindgen-tests/tests/expectations/tests/const_array_fn_arg.rs @@ -1,4 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn f(a: *const ::std::os::raw::c_int); } diff --git a/bindgen-tests/tests/expectations/tests/const_array_typedef.rs b/bindgen-tests/tests/expectations/tests/const_array_typedef.rs index a9ddc0c85e..034856d359 100644 --- a/bindgen-tests/tests/expectations/tests/const_array_typedef.rs +++ b/bindgen-tests/tests/expectations/tests/const_array_typedef.rs @@ -11,18 +11,18 @@ const _: () = { ["Offset of field: strct::field"][::std::mem::offset_of!(strct, field) - 0usize]; }; pub type typ = [strct; 1usize]; -extern "C" { +unsafe extern "C" { pub static mut w: typ; } -extern "C" { +unsafe extern "C" { pub static mut x: *mut strct; } -extern "C" { +unsafe extern "C" { pub static y: typ; } -extern "C" { +unsafe extern "C" { pub static mut z: *const strct; } -extern "C" { +unsafe extern "C" { pub fn function(a: *const strct, b: *const strct); } diff --git a/bindgen-tests/tests/expectations/tests/const_multidim_array_fn_arg.rs b/bindgen-tests/tests/expectations/tests/const_multidim_array_fn_arg.rs index 0c4670b0ed..db0ce114fb 100644 --- a/bindgen-tests/tests/expectations/tests/const_multidim_array_fn_arg.rs +++ b/bindgen-tests/tests/expectations/tests/const_multidim_array_fn_arg.rs @@ -1,4 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn f(a: *const [::std::os::raw::c_int; 1usize]); } diff --git a/bindgen-tests/tests/expectations/tests/const_ptr.rs b/bindgen-tests/tests/expectations/tests/const_ptr.rs index c08aa73d7e..9b9e38c1e7 100644 --- a/bindgen-tests/tests/expectations/tests/const_ptr.rs +++ b/bindgen-tests/tests/expectations/tests/const_ptr.rs @@ -1,4 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn foo(bar: *const ::std::os::raw::c_void); } diff --git a/bindgen-tests/tests/expectations/tests/const_resolved_ty.rs b/bindgen-tests/tests/expectations/tests/const_resolved_ty.rs index 20a124b474..ed49b69f64 100644 --- a/bindgen-tests/tests/expectations/tests/const_resolved_ty.rs +++ b/bindgen-tests/tests/expectations/tests/const_resolved_ty.rs @@ -1,4 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn foo(foo: *const u8); } diff --git a/bindgen-tests/tests/expectations/tests/constify-module-enums-basic.rs b/bindgen-tests/tests/expectations/tests/constify-module-enums-basic.rs index ec0e51c49e..aad696d074 100644 --- a/bindgen-tests/tests/expectations/tests/constify-module-enums-basic.rs +++ b/bindgen-tests/tests/expectations/tests/constify-module-enums-basic.rs @@ -1,5 +1,7 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub mod foo { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const THIS: Type = 0; pub const SHOULD_BE: Type = 1; @@ -29,14 +31,14 @@ impl Default for bar { } } } -extern "C" { +unsafe extern "C" { pub fn func1( arg1: foo::Type, arg2: *mut foo::Type, arg3: *mut *mut foo::Type, ) -> *mut foo::Type; } -extern "C" { +unsafe extern "C" { pub fn func2( arg1: foo_alias1, arg2: *mut foo_alias1, diff --git a/bindgen-tests/tests/expectations/tests/constify-module-enums-namespace.rs b/bindgen-tests/tests/expectations/tests/constify-module-enums-namespace.rs index 883478a824..cdf6e7ebb4 100644 --- a/bindgen-tests/tests/expectations/tests/constify-module-enums-namespace.rs +++ b/bindgen-tests/tests/expectations/tests/constify-module-enums-namespace.rs @@ -10,6 +10,8 @@ pub mod root { #[allow(unused_imports)] use self::super::super::super::root; pub mod foo { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const THIS: Type = 0; pub const SHOULD_BE: Type = 1; diff --git a/bindgen-tests/tests/expectations/tests/constify-module-enums-shadow-name.rs b/bindgen-tests/tests/expectations/tests/constify-module-enums-shadow-name.rs index b5e4243c94..987f4463a2 100644 --- a/bindgen-tests/tests/expectations/tests/constify-module-enums-shadow-name.rs +++ b/bindgen-tests/tests/expectations/tests/constify-module-enums-shadow-name.rs @@ -1,5 +1,7 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub mod foo { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const Type: Type = 0; pub const Type_: Type = 1; diff --git a/bindgen-tests/tests/expectations/tests/constify-module-enums-simple-alias.rs b/bindgen-tests/tests/expectations/tests/constify-module-enums-simple-alias.rs index 63d48ef795..5f7b9ede4a 100644 --- a/bindgen-tests/tests/expectations/tests/constify-module-enums-simple-alias.rs +++ b/bindgen-tests/tests/expectations/tests/constify-module-enums-simple-alias.rs @@ -1,5 +1,7 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub mod Foo { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_int; pub const Variant1: Type = 0; pub const Variant2: Type = 1; diff --git a/bindgen-tests/tests/expectations/tests/constify-module-enums-simple-nonamespace.rs b/bindgen-tests/tests/expectations/tests/constify-module-enums-simple-nonamespace.rs index 80fa0734da..dc59f5fc1d 100644 --- a/bindgen-tests/tests/expectations/tests/constify-module-enums-simple-nonamespace.rs +++ b/bindgen-tests/tests/expectations/tests/constify-module-enums-simple-nonamespace.rs @@ -1,5 +1,7 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub mod one_Foo { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_int; pub const Variant1: Type = 0; pub const Variant2: Type = 1; diff --git a/bindgen-tests/tests/expectations/tests/constify-module-enums-types.rs b/bindgen-tests/tests/expectations/tests/constify-module-enums-types.rs index 754f6ceedb..a4a69fd72d 100644 --- a/bindgen-tests/tests/expectations/tests/constify-module-enums-types.rs +++ b/bindgen-tests/tests/expectations/tests/constify-module-enums-types.rs @@ -1,5 +1,15 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type Uint = ::std::os::raw::c_uint; +pub mod ExplicitTypeAlias { + #[allow(unused_imports)] + use super::*; + pub type Type = Uint; + pub const SOME_CONSTANT: Type = 0; + pub const SOME_OTHER_CONSTANT: Type = 1; +} pub mod foo { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const THIS: Type = 0; pub const SHOULD_BE: Type = 1; @@ -8,12 +18,16 @@ pub mod foo { pub const AND_ALSO_THIS: Type = 42; } pub mod anon_enum { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const Variant1: Type = 0; pub const Variant2: Type = 1; pub const Variant3: Type = 2; } pub mod ns1_foo { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const THIS: Type = 0; pub const SHOULD_BE: Type = 1; @@ -21,6 +35,8 @@ pub mod ns1_foo { pub const ALSO_THIS: Type = 42; } pub mod ns2_Foo { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_int; pub const Variant1: Type = 0; pub const Variant2: Type = 1; @@ -90,6 +106,8 @@ impl Default for Baz { } } pub mod one_Foo { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_int; pub const Variant1: Type = 0; pub const Variant2: Type = 1; @@ -114,7 +132,7 @@ impl Default for Bar { } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z5func13fooPS_PS0_"] pub fn func1( arg1: foo::Type, @@ -122,7 +140,7 @@ extern "C" { arg3: *mut *mut foo::Type, ) -> *mut foo::Type; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z5func23fooPS_PS0_"] pub fn func2( arg1: foo_alias1, @@ -145,11 +163,11 @@ impl Default for Thing { } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z5func35ThingI3fooE"] pub fn func3(arg1: Thing) -> foo::Type; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z5func45ThingIS_I3fooEE"] pub fn func4(arg1: Thing>) -> foo::Type; } diff --git a/bindgen-tests/tests/expectations/tests/constructor-tp.rs b/bindgen-tests/tests/expectations/tests/constructor-tp.rs index 1a6e9c40dc..2585311d29 100644 --- a/bindgen-tests/tests/expectations/tests/constructor-tp.rs +++ b/bindgen-tests/tests/expectations/tests/constructor-tp.rs @@ -14,7 +14,7 @@ const _: () = { ["Size of Bar"][::std::mem::size_of::() - 1usize]; ["Alignment of Bar"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3BarC1Ev"] pub fn Bar_Bar(this: *mut Bar); } diff --git a/bindgen-tests/tests/expectations/tests/constructors.rs b/bindgen-tests/tests/expectations/tests/constructors.rs index 9da761e40a..45c29e61e5 100644 --- a/bindgen-tests/tests/expectations/tests/constructors.rs +++ b/bindgen-tests/tests/expectations/tests/constructors.rs @@ -9,14 +9,14 @@ const _: () = { ["Size of TestOverload"][::std::mem::size_of::() - 1usize]; ["Alignment of TestOverload"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN12TestOverloadC1Ei"] pub fn TestOverload_TestOverload( this: *mut TestOverload, arg1: ::std::os::raw::c_int, ); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN12TestOverloadC1Ed"] pub fn TestOverload_TestOverload1(this: *mut TestOverload, arg1: f64); } @@ -46,7 +46,7 @@ const _: () = { "Alignment of TestPublicNoArgs", ][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN16TestPublicNoArgsC1Ev"] pub fn TestPublicNoArgs_TestPublicNoArgs(this: *mut TestPublicNoArgs); } diff --git a/bindgen-tests/tests/expectations/tests/constructors_1_33.rs b/bindgen-tests/tests/expectations/tests/constructors_1_33.rs index 0563b4e65d..5dbda00007 100644 --- a/bindgen-tests/tests/expectations/tests/constructors_1_33.rs +++ b/bindgen-tests/tests/expectations/tests/constructors_1_33.rs @@ -4,16 +4,12 @@ pub struct TestOverload { pub _address: u8, } -#[test] -fn bindgen_test_layout_TestOverload() { - assert_eq!(::std::mem::size_of::(), 1usize, "Size of TestOverload"); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - "Alignment of TestOverload", - ); -} -extern "C" { +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of TestOverload"][::std::mem::size_of::() - 1usize]; + ["Alignment of TestOverload"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { /// Calling this should use `mem::unintialized()` and not `MaybeUninit()` as only rust 1.36 includes that. #[link_name = "\u{1}_ZN12TestOverloadC1Ei"] pub fn TestOverload_TestOverload( @@ -21,7 +17,7 @@ extern "C" { arg1: ::std::os::raw::c_int, ); } -extern "C" { +unsafe extern "C" { /// Calling this should use `mem::unintialized()` and not `MaybeUninit()` as only rust 1.36 includes that. #[link_name = "\u{1}_ZN12TestOverloadC1Ed"] pub fn TestOverload_TestOverload1(this: *mut TestOverload, arg1: f64); @@ -29,15 +25,15 @@ extern "C" { impl TestOverload { #[inline] pub unsafe fn new(arg1: ::std::os::raw::c_int) -> Self { - let mut __bindgen_tmp = ::std::mem::uninitialized(); - TestOverload_TestOverload(&mut __bindgen_tmp, arg1); - __bindgen_tmp + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + TestOverload_TestOverload(__bindgen_tmp.as_mut_ptr(), arg1); + __bindgen_tmp.assume_init() } #[inline] pub unsafe fn new1(arg1: f64) -> Self { - let mut __bindgen_tmp = ::std::mem::uninitialized(); - TestOverload_TestOverload1(&mut __bindgen_tmp, arg1); - __bindgen_tmp + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + TestOverload_TestOverload1(__bindgen_tmp.as_mut_ptr(), arg1); + __bindgen_tmp.assume_init() } } #[repr(C)] @@ -45,28 +41,22 @@ impl TestOverload { pub struct TestPublicNoArgs { pub _address: u8, } -#[test] -fn bindgen_test_layout_TestPublicNoArgs() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - "Size of TestPublicNoArgs", - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of TestPublicNoArgs"][::std::mem::size_of::() - 1usize]; + [ "Alignment of TestPublicNoArgs", - ); -} -extern "C" { + ][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { #[link_name = "\u{1}_ZN16TestPublicNoArgsC1Ev"] pub fn TestPublicNoArgs_TestPublicNoArgs(this: *mut TestPublicNoArgs); } impl TestPublicNoArgs { #[inline] pub unsafe fn new() -> Self { - let mut __bindgen_tmp = ::std::mem::uninitialized(); - TestPublicNoArgs_TestPublicNoArgs(&mut __bindgen_tmp); - __bindgen_tmp + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + TestPublicNoArgs_TestPublicNoArgs(__bindgen_tmp.as_mut_ptr()); + __bindgen_tmp.assume_init() } } diff --git a/bindgen-tests/tests/expectations/tests/decl_extern_int_twice.rs b/bindgen-tests/tests/expectations/tests/decl_extern_int_twice.rs index 8be0ea58e9..122d41a12d 100644 --- a/bindgen-tests/tests/expectations/tests/decl_extern_int_twice.rs +++ b/bindgen-tests/tests/expectations/tests/decl_extern_int_twice.rs @@ -1,4 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub static mut foo: ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/decl_ptr_to_array.rs b/bindgen-tests/tests/expectations/tests/decl_ptr_to_array.rs index 08cf113a4c..a559d33b4a 100644 --- a/bindgen-tests/tests/expectations/tests/decl_ptr_to_array.rs +++ b/bindgen-tests/tests/expectations/tests/decl_ptr_to_array.rs @@ -1,4 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub static mut foo: *mut [::std::os::raw::c_int; 1usize]; } diff --git a/bindgen-tests/tests/expectations/tests/default-enum-style-constified-module.rs b/bindgen-tests/tests/expectations/tests/default-enum-style-constified-module.rs index c9897de70b..2a75aa8d86 100644 --- a/bindgen-tests/tests/expectations/tests/default-enum-style-constified-module.rs +++ b/bindgen-tests/tests/expectations/tests/default-enum-style-constified-module.rs @@ -1,10 +1,12 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub mod Foo { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const bar: Type = 0; pub const baz: Type = 1; pub const blap: Type = 2; } -extern "C" { +unsafe extern "C" { pub fn func(x: Foo::Type); } diff --git a/bindgen-tests/tests/expectations/tests/default-macro-constant-type-signed.rs b/bindgen-tests/tests/expectations/tests/default-macro-constant-type-signed.rs index db4eaa99bd..7fca57b6b9 100644 --- a/bindgen-tests/tests/expectations/tests/default-macro-constant-type-signed.rs +++ b/bindgen-tests/tests/expectations/tests/default-macro-constant-type-signed.rs @@ -30,7 +30,7 @@ pub const MIN_U32_Minus1: i32 = -1; pub const MIN_I32_Minus1: i64 = -2147483649; pub const LONG12: i64 = 123456789012; pub const LONG_12: i64 = -123456789012; -extern "C" { +unsafe extern "C" { pub fn foo( arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int, @@ -40,7 +40,7 @@ extern "C" { arg6: ::std::os::raw::c_schar, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn bar( arg1: ::std::os::raw::c_long, arg2: ::std::os::raw::c_longlong, diff --git a/bindgen-tests/tests/expectations/tests/default-macro-constant-type-unsigned.rs b/bindgen-tests/tests/expectations/tests/default-macro-constant-type-unsigned.rs index bc122e981f..d34d050a1a 100644 --- a/bindgen-tests/tests/expectations/tests/default-macro-constant-type-unsigned.rs +++ b/bindgen-tests/tests/expectations/tests/default-macro-constant-type-unsigned.rs @@ -30,7 +30,7 @@ pub const MIN_U32_Minus1: i32 = -1; pub const MIN_I32_Minus1: i64 = -2147483649; pub const LONG12: u64 = 123456789012; pub const LONG_12: i64 = -123456789012; -extern "C" { +unsafe extern "C" { pub fn foo( arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int, @@ -40,7 +40,7 @@ extern "C" { arg6: ::std::os::raw::c_schar, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn bar( arg1: ::std::os::raw::c_long, arg2: ::std::os::raw::c_longlong, diff --git a/bindgen-tests/tests/expectations/tests/default-macro-constant-type.rs b/bindgen-tests/tests/expectations/tests/default-macro-constant-type.rs index bc122e981f..d34d050a1a 100644 --- a/bindgen-tests/tests/expectations/tests/default-macro-constant-type.rs +++ b/bindgen-tests/tests/expectations/tests/default-macro-constant-type.rs @@ -30,7 +30,7 @@ pub const MIN_U32_Minus1: i32 = -1; pub const MIN_I32_Minus1: i64 = -2147483649; pub const LONG12: u64 = 123456789012; pub const LONG_12: i64 = -123456789012; -extern "C" { +unsafe extern "C" { pub fn foo( arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int, @@ -40,7 +40,7 @@ extern "C" { arg6: ::std::os::raw::c_schar, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn bar( arg1: ::std::os::raw::c_long, arg2: ::std::os::raw::c_longlong, diff --git a/bindgen-tests/tests/expectations/tests/default-template-parameter.rs b/bindgen-tests/tests/expectations/tests/default-template-parameter.rs index 797fc03253..67f8a486de 100644 --- a/bindgen-tests/tests/expectations/tests/default-template-parameter.rs +++ b/bindgen-tests/tests/expectations/tests/default-template-parameter.rs @@ -25,7 +25,7 @@ const _: () = { "Align of template specialization: Foo_open0_bool__int_close0", ][::std::mem::align_of::>() - 4usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZL3bar"] pub static mut bar: Foo; } diff --git a/bindgen-tests/tests/expectations/tests/default_visibility_crate.rs b/bindgen-tests/tests/expectations/tests/default_visibility_crate.rs index aef1a61a08..aeefb2e0f9 100644 --- a/bindgen-tests/tests/expectations/tests/default_visibility_crate.rs +++ b/bindgen-tests/tests/expectations/tests/default_visibility_crate.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,6 +126,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -92,7 +154,6 @@ pub struct Point { #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Color { - pub(crate) _bitfield_align_1: [u8; 0], pub(crate) _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, } impl Color { @@ -108,6 +169,30 @@ impl Color { } } #[inline] + pub(crate) unsafe fn r_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + pub(crate) unsafe fn set_r_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub(crate) fn g(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } } @@ -119,6 +204,30 @@ impl Color { } } #[inline] + pub(crate) unsafe fn g_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) as u8, + ) + } + } + #[inline] + pub(crate) unsafe fn set_g_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub(crate) fn b(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u8) } } @@ -130,6 +239,30 @@ impl Color { } } #[inline] + pub(crate) unsafe fn b_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 1u8) as u8, + ) + } + } + #[inline] + pub(crate) unsafe fn set_b_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 2usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub(crate) fn new_bitfield_1( r: ::std::os::raw::c_char, g: ::std::os::raw::c_char, diff --git a/bindgen-tests/tests/expectations/tests/default_visibility_private.rs b/bindgen-tests/tests/expectations/tests/default_visibility_private.rs index 8b3099c0d8..dceed75e36 100644 --- a/bindgen-tests/tests/expectations/tests/default_visibility_private.rs +++ b/bindgen-tests/tests/expectations/tests/default_visibility_private.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,6 +126,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -92,7 +154,6 @@ pub struct Point { #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Color { - _bitfield_align_1: [u8; 0], _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, } impl Color { @@ -108,6 +169,30 @@ impl Color { } } #[inline] + unsafe fn r_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + unsafe fn set_r_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] fn g(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } } @@ -119,6 +204,30 @@ impl Color { } } #[inline] + unsafe fn g_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) as u8, + ) + } + } + #[inline] + unsafe fn set_g_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] fn b(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u8) } } @@ -130,6 +239,30 @@ impl Color { } } #[inline] + unsafe fn b_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 1u8) as u8, + ) + } + } + #[inline] + unsafe fn set_b_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 2usize, + 1u8, + val as u64, + ) + } + } + #[inline] fn new_bitfield_1( r: ::std::os::raw::c_char, g: ::std::os::raw::c_char, diff --git a/bindgen-tests/tests/expectations/tests/default_visibility_private_respects_cxx_access_spec.rs b/bindgen-tests/tests/expectations/tests/default_visibility_private_respects_cxx_access_spec.rs index 29fbb3a893..f43be84bb0 100644 --- a/bindgen-tests/tests/expectations/tests/default_visibility_private_respects_cxx_access_spec.rs +++ b/bindgen-tests/tests/expectations/tests/default_visibility_private_respects_cxx_access_spec.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,6 +126,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -92,7 +154,6 @@ pub struct Point { #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Color { - _bitfield_align_1: [u8; 0], _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, } impl Color { @@ -108,6 +169,30 @@ impl Color { } } #[inline] + pub unsafe fn r_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_r_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn g(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } } @@ -119,6 +204,30 @@ impl Color { } } #[inline] + pub unsafe fn g_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_g_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b(&self) -> ::std::os::raw::c_char { unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u8) } } @@ -130,6 +239,30 @@ impl Color { } } #[inline] + pub unsafe fn b_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 2usize, + 1u8, + val as u64, + ) + } + } + #[inline] fn new_bitfield_1( r: ::std::os::raw::c_char, g: ::std::os::raw::c_char, diff --git a/bindgen-tests/tests/expectations/tests/deleted-function.rs b/bindgen-tests/tests/expectations/tests/deleted-function.rs index 913e2d4b4a..fc8588121f 100644 --- a/bindgen-tests/tests/expectations/tests/deleted-function.rs +++ b/bindgen-tests/tests/expectations/tests/deleted-function.rs @@ -9,11 +9,11 @@ const _: () = { ["Size of A"][::std::mem::size_of::() - 1usize]; ["Alignment of A"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1A17inline_definitionEv"] pub fn A_inline_definition(this: *mut A); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1A22out_of_line_definitionEv"] pub fn A_out_of_line_definition(this: *mut A); } @@ -47,7 +47,7 @@ const _: () = { ["Size of C"][::std::mem::size_of::() - 1usize]; ["Alignment of C"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1CC1ERS_"] pub fn C_C(this: *mut C, arg1: *mut C); } diff --git a/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs b/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs index feded416f7..7fa8bc41ab 100644 --- a/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs +++ b/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,39 +126,50 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } /** Because this struct have array larger than 32 items and --with-derive-partialeq --impl-partialeq --impl-debug is provided, this struct should manually implement `Debug` and `PartialEq`.*/ #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] pub struct Foo { pub large: [::std::os::raw::c_int; 33usize], - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, pub __bindgen_padding_0: u16, } -#[test] -fn bindgen_test_layout_Foo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 136usize, "Size of Foo"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of Foo"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).large) as usize - ptr as usize }, - 0usize, - "Offset of field: Foo::large", - ); -} -extern "C" { +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 136usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Foo::large"][::std::mem::offset_of!(Foo, large) - 0usize]; +}; +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo4typeEv"] pub fn Foo_type(this: *mut Foo) -> ::std::os::raw::c_char; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo9set_type_Ec"] pub fn Foo_set_type_(this: *mut Foo, c: ::std::os::raw::c_char); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo8set_typeEc"] pub fn Foo_set_type(this: *mut Foo, c: ::std::os::raw::c_char); } @@ -127,27 +182,6 @@ impl Default for Foo { } } } -impl ::std::fmt::Debug for Foo { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!( - f, - "Foo {{ large: [{}], type_ : {:?}, }}", - self - .large - .iter() - .enumerate() - .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v)) - .collect::(), - self.type__bindgen_bitfield(), - ) - } -} -impl ::std::cmp::PartialEq for Foo { - fn eq(&self, other: &Foo) -> bool { - &self.large[..] == &other.large[..] - && self.type__bindgen_bitfield() == other.type__bindgen_bitfield() - } -} impl Foo { #[inline] pub fn type__bindgen_bitfield(&self) -> ::std::os::raw::c_char { @@ -161,6 +195,35 @@ impl Foo { } } #[inline] + pub unsafe fn type__bindgen_bitfield_raw( + this: *const Self, + ) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 3u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_type__bindgen_bitfield_raw( + this: *mut Self, + val: ::std::os::raw::c_char, + ) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 3u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( type__bindgen_bitfield: ::std::os::raw::c_char, ) -> __BindgenBitfieldUnit<[u8; 2usize]> { diff --git a/bindgen-tests/tests/expectations/tests/derive-clone.rs b/bindgen-tests/tests/expectations/tests/derive-clone.rs index d903afa06f..ccbdf5bd70 100644 --- a/bindgen-tests/tests/expectations/tests/derive-clone.rs +++ b/bindgen-tests/tests/expectations/tests/derive-clone.rs @@ -1,30 +1,20 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] /// This struct should derive `Clone`. #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct ShouldDeriveClone { pub large: [::std::os::raw::c_int; 33usize], } -#[test] -fn bindgen_test_layout_ShouldDeriveClone() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 132usize, - "Size of ShouldDeriveClone", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ShouldDeriveClone"][::std::mem::size_of::() - 132usize]; + [ "Alignment of ShouldDeriveClone", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).large) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: ShouldDeriveClone::large", - ); -} + ][::std::mem::offset_of!(ShouldDeriveClone, large) - 0usize]; +}; impl Default for ShouldDeriveClone { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); diff --git a/bindgen-tests/tests/expectations/tests/derive-clone_1_0.rs b/bindgen-tests/tests/expectations/tests/derive-clone_1_0.rs deleted file mode 100644 index 7b3a00738c..0000000000 --- a/bindgen-tests/tests/expectations/tests/derive-clone_1_0.rs +++ /dev/null @@ -1,42 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -/** Since builtin `Clone` impls were introduced in Rust 1.21 this struct - should impl `Clone` "manually".*/ -#[repr(C)] -#[derive(Copy)] -pub struct ShouldImplClone { - pub large: [::std::os::raw::c_int; 33usize], -} -#[test] -fn bindgen_test_layout_ShouldImplClone() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 132usize, - "Size of ShouldImplClone", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of ShouldImplClone", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).large) as usize - ptr as usize }, - 0usize, - "Offset of field: ShouldImplClone::large", - ); -} -impl Clone for ShouldImplClone { - fn clone(&self) -> Self { - *self - } -} -impl Default for ShouldImplClone { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-1-51.rs b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-1-51.rs new file mode 100644 index 0000000000..87cbb7346c --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-1-51.rs @@ -0,0 +1,263 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit { + storage: Storage, +} +impl __BindgenBitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage } + } +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + fn extract_bit(byte: u8, index: usize) -> bool { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct C { + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub large_array: [::std::os::raw::c_int; 50usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 204usize]; + ["Alignment of C"][::std::mem::align_of::() - 4usize]; + ["Offset of field: C::large_array"][::std::mem::offset_of!(C, large_array) - 4usize]; +}; +impl Default for C { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl C { + #[inline] + pub fn a(&self) -> bool { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + } + #[inline] + pub fn set_a(&mut self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub unsafe fn a_raw(this: *const Self) -> bool { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_a_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] + pub fn b(&self) -> bool { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 7u8) as u8) } + } + #[inline] + pub fn set_b(&mut self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(1usize, 7u8, val as u64) + } + } + #[inline] + pub unsafe fn b_raw(this: *const Self) -> bool { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 7u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 7u8, + val as u64, + ) + } + } + #[inline] + pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 1u8, + { + let a: u8 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 1usize, + 7u8, + { + let b: u8 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs index 64c20f91ba..937ad4ad0c 100644 --- a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs +++ b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs @@ -16,10 +16,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -29,21 +26,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -66,6 +90,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -83,26 +127,39 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct C { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - pub large_array: [::std::os::raw::c_int; 50usize], + pub large_array: [::core::ffi::c_int; 50usize], } -#[test] -fn bindgen_test_layout_C() { - const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::core::mem::size_of::(), 204usize, "Size of C"); - assert_eq!(::core::mem::align_of::(), 4usize, "Alignment of C"); - assert_eq!( - unsafe { ::core::ptr::addr_of!((*ptr).large_array) as usize - ptr as usize }, - 4usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::core::mem::size_of::() - 204usize]; + ["Alignment of C"][::core::mem::align_of::() - 4usize]; + [ "Offset of field: C::large_array", - ); -} + ][::core::mem::offset_of!(C, large_array) - 4usize]; +}; impl Default for C { fn default() -> Self { let mut s = ::core::mem::MaybeUninit::::uninit(); @@ -112,11 +169,6 @@ impl Default for C { } } } -impl ::core::fmt::Debug for C { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write!(f, "C {{ a : {:?}, b : {:?}, large_array: [...] }}", self.a(), self.b()) - } -} impl C { #[inline] pub fn a(&self) -> bool { @@ -130,6 +182,31 @@ impl C { } } #[inline] + pub unsafe fn a_raw(this: *const Self) -> bool { + unsafe { + ::core::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::core::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_a_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::core::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::core::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b(&self) -> bool { unsafe { ::core::mem::transmute(self._bitfield_1.get(1usize, 7u8) as u8) } } @@ -141,6 +218,31 @@ impl C { } } #[inline] + pub unsafe fn b_raw(this: *const Self) -> bool { + unsafe { + ::core::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::core::ptr::addr_of!((*this)._bitfield_1), 1usize, 7u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::core::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::core::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 7u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); __bindgen_bitfield_unit diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.rs b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.rs index 0471b48bfa..87cbb7346c 100644 --- a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,26 +126,37 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct C { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub large_array: [::std::os::raw::c_int; 50usize], } -#[test] -fn bindgen_test_layout_C() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 204usize, "Size of C"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of C"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).large_array) as usize - ptr as usize }, - 4usize, - "Offset of field: C::large_array", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 204usize]; + ["Alignment of C"][::std::mem::align_of::() - 4usize]; + ["Offset of field: C::large_array"][::std::mem::offset_of!(C, large_array) - 4usize]; +}; impl Default for C { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -111,22 +166,6 @@ impl Default for C { } } } -impl ::std::fmt::Debug for C { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!( - f, - "C {{ a : {:?}, b : {:?}, large_array: [{}] }}", - self.a(), - self.b(), - self - .large_array - .iter() - .enumerate() - .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v)) - .collect::(), - ) - } -} impl C { #[inline] pub fn a(&self) -> bool { @@ -140,6 +179,30 @@ impl C { } } #[inline] + pub unsafe fn a_raw(this: *const Self) -> bool { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_a_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b(&self) -> bool { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 7u8) as u8) } } @@ -151,6 +214,30 @@ impl C { } } #[inline] + pub unsafe fn b_raw(this: *const Self) -> bool { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 7u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 7u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); __bindgen_bitfield_unit diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-function-pointer.rs b/bindgen-tests/tests/expectations/tests/derive-debug-function-pointer.rs index 9077201a77..eaaa8ef9d4 100644 --- a/bindgen-tests/tests/expectations/tests/derive-debug-function-pointer.rs +++ b/bindgen-tests/tests/expectations/tests/derive-debug-function-pointer.rs @@ -1,6 +1,6 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct Nice { pub pointer: Nice_Function, pub large_array: [::std::os::raw::c_int; 34usize], @@ -8,23 +8,15 @@ pub struct Nice { pub type Nice_Function = ::std::option::Option< unsafe extern "C" fn(data: ::std::os::raw::c_int), >; -#[test] -fn bindgen_test_layout_Nice() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 144usize, "Size of Nice"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of Nice"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pointer) as usize - ptr as usize }, - 0usize, - "Offset of field: Nice::pointer", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).large_array) as usize - ptr as usize }, - 8usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Nice"][::std::mem::size_of::() - 144usize]; + ["Alignment of Nice"][::std::mem::align_of::() - 8usize]; + ["Offset of field: Nice::pointer"][::std::mem::offset_of!(Nice, pointer) - 0usize]; + [ "Offset of field: Nice::large_array", - ); -} + ][::std::mem::offset_of!(Nice, large_array) - 8usize]; +}; impl Default for Nice { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -34,18 +26,3 @@ impl Default for Nice { } } } -impl ::std::fmt::Debug for Nice { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!( - f, - "Nice {{ pointer: {:?}, large_array: [{}] }}", - self.pointer, - self - .large_array - .iter() - .enumerate() - .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v)) - .collect::(), - ) - } -} diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-generic.rs b/bindgen-tests/tests/expectations/tests/derive-debug-generic.rs index de6ce385ac..86e530463f 100644 --- a/bindgen-tests/tests/expectations/tests/derive-debug-generic.rs +++ b/bindgen-tests/tests/expectations/tests/derive-debug-generic.rs @@ -1,5 +1,6 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] +#[derive(Debug)] pub struct Generic { pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub t: [T; 40usize], @@ -13,8 +14,3 @@ impl Default for Generic { } } } -impl ::std::fmt::Debug for Generic { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(f, "Generic {{ t: Array with length 40 }}") - } -} diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-opaque-template-instantiation.rs b/bindgen-tests/tests/expectations/tests/derive-debug-opaque-template-instantiation.rs index d586278614..9d75e74d77 100644 --- a/bindgen-tests/tests/expectations/tests/derive-debug-opaque-template-instantiation.rs +++ b/bindgen-tests/tests/expectations/tests/derive-debug-opaque-template-instantiation.rs @@ -1,31 +1,20 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] #[repr(C)] -pub struct Instance { - pub val: [u32; 50usize], -} -#[test] -fn bindgen_test_layout_Instance() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 200usize, "Size of Instance"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of Instance"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).val) as usize - ptr as usize }, - 0usize, - "Offset of field: Instance::val", - ); -} -impl Default for Instance { +pub struct __BindgenOpaqueArray(pub T); +impl Default for __BindgenOpaqueArray<[T; N]> { fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } + Self([::default(); N]) } } -impl ::std::fmt::Debug for Instance { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(f, "Instance {{ val: opaque }}") - } +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Instance { + pub val: __BindgenOpaqueArray<[u32; 50usize]>, } +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Instance"][::std::mem::size_of::() - 200usize]; + ["Alignment of Instance"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Instance::val"][::std::mem::offset_of!(Instance, val) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-opaque.rs b/bindgen-tests/tests/expectations/tests/derive-debug-opaque.rs index 13ddfd5ada..4ec1fb2a35 100644 --- a/bindgen-tests/tests/expectations/tests/derive-debug-opaque.rs +++ b/bindgen-tests/tests/expectations/tests/derive-debug-opaque.rs @@ -1,55 +1,33 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] #[repr(C)] -#[repr(align(4))] -pub struct Opaque { - pub _bindgen_opaque_blob: [u32; 41usize], -} -#[test] -fn bindgen_test_layout_Opaque() { - assert_eq!(::std::mem::size_of::(), 164usize, "Size of Opaque"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of Opaque"); -} -impl Default for Opaque { +pub struct __BindgenOpaqueArray(pub T); +impl Default for __BindgenOpaqueArray<[T; N]> { fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } + Self([::default(); N]) } } -impl ::std::fmt::Debug for Opaque { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(f, "Opaque {{ opaque }}") - } +#[repr(C)] +#[repr(align(4))] +#[derive(Debug, Default, Copy, Clone)] +pub struct Opaque { + pub _bindgen_opaque_blob: __BindgenOpaqueArray<[u32; 41usize]>, } +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Opaque"][::std::mem::size_of::() - 164usize]; + ["Alignment of Opaque"][::std::mem::align_of::() - 4usize]; +}; #[repr(C)] +#[derive(Debug, Default, Copy, Clone)] pub struct OpaqueUser { pub opaque: Opaque, } -#[test] -fn bindgen_test_layout_OpaqueUser() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 164usize, "Size of OpaqueUser"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of OpaqueUser"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).opaque) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of OpaqueUser"][::std::mem::size_of::() - 164usize]; + ["Alignment of OpaqueUser"][::std::mem::align_of::() - 4usize]; + [ "Offset of field: OpaqueUser::opaque", - ); -} -impl Default for OpaqueUser { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -impl ::std::fmt::Debug for OpaqueUser { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(f, "OpaqueUser {{ opaque: {:?} }}", self.opaque) - } -} + ][::std::mem::offset_of!(OpaqueUser, opaque) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/derive-partialeq-base.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-base.rs index d0768416ec..3ca262fe36 100644 --- a/bindgen-tests/tests/expectations/tests/derive-partialeq-base.rs +++ b/bindgen-tests/tests/expectations/tests/derive-partialeq-base.rs @@ -1,21 +1,15 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] pub struct Base { pub large: [::std::os::raw::c_int; 33usize], } -#[test] -fn bindgen_test_layout_Base() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 132usize, "Size of Base"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of Base"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).large) as usize - ptr as usize }, - 0usize, - "Offset of field: Base::large", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Base"][::std::mem::size_of::() - 132usize]; + ["Alignment of Base"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Base::large"][::std::mem::offset_of!(Base, large) - 0usize]; +}; impl Default for Base { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -25,29 +19,20 @@ impl Default for Base { } } } -impl ::std::cmp::PartialEq for Base { - fn eq(&self, other: &Base) -> bool { - &self.large[..] == &other.large[..] - } -} #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] pub struct ShouldDerivePartialEq { pub _base: Base, } -#[test] -fn bindgen_test_layout_ShouldDerivePartialEq() { - assert_eq!( - ::std::mem::size_of::(), - 132usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of ShouldDerivePartialEq", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 132usize]; + [ "Alignment of ShouldDerivePartialEq", - ); -} + ][::std::mem::align_of::() - 4usize]; +}; impl Default for ShouldDerivePartialEq { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -57,8 +42,3 @@ impl Default for ShouldDerivePartialEq { } } } -impl ::std::cmp::PartialEq for ShouldDerivePartialEq { - fn eq(&self, other: &ShouldDerivePartialEq) -> bool { - self._base == other._base - } -} diff --git a/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs index 7c325620cf..b8da88e2a7 100644 --- a/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,26 +126,37 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] pub struct C { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub large_array: [::std::os::raw::c_int; 50usize], } -#[test] -fn bindgen_test_layout_C() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 204usize, "Size of C"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of C"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).large_array) as usize - ptr as usize }, - 4usize, - "Offset of field: C::large_array", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::std::mem::size_of::() - 204usize]; + ["Alignment of C"][::std::mem::align_of::() - 4usize]; + ["Offset of field: C::large_array"][::std::mem::offset_of!(C, large_array) - 4usize]; +}; impl Default for C { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -111,12 +166,6 @@ impl Default for C { } } } -impl ::std::cmp::PartialEq for C { - fn eq(&self, other: &C) -> bool { - self.a() == other.a() && self.b() == other.b() - && &self.large_array[..] == &other.large_array[..] - } -} impl C { #[inline] pub fn a(&self) -> bool { @@ -130,6 +179,30 @@ impl C { } } #[inline] + pub unsafe fn a_raw(this: *const Self) -> bool { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_a_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b(&self) -> bool { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 7u8) as u8) } } @@ -141,6 +214,30 @@ impl C { } } #[inline] + pub unsafe fn b_raw(this: *const Self) -> bool { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 7u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 7u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); __bindgen_bitfield_unit diff --git a/bindgen-tests/tests/expectations/tests/derive-partialeq-core.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-core.rs index 3a7639f9de..9a36b8f8c7 100644 --- a/bindgen-tests/tests/expectations/tests/derive-partialeq-core.rs +++ b/bindgen-tests/tests/expectations/tests/derive-partialeq-core.rs @@ -1,22 +1,18 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] extern crate core; #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] pub struct C { - pub large_array: [::std::os::raw::c_int; 420usize], + pub large_array: [::core::ffi::c_int; 420usize], } -#[test] -fn bindgen_test_layout_C() { - const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::core::mem::size_of::(), 1680usize, "Size of C"); - assert_eq!(::core::mem::align_of::(), 4usize, "Alignment of C"); - assert_eq!( - unsafe { ::core::ptr::addr_of!((*ptr).large_array) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of C"][::core::mem::size_of::() - 1680usize]; + ["Alignment of C"][::core::mem::align_of::() - 4usize]; + [ "Offset of field: C::large_array", - ); -} + ][::core::mem::offset_of!(C, large_array) - 0usize]; +}; impl Default for C { fn default() -> Self { let mut s = ::core::mem::MaybeUninit::::uninit(); @@ -26,8 +22,3 @@ impl Default for C { } } } -impl ::core::cmp::PartialEq for C { - fn eq(&self, other: &C) -> bool { - &self.large_array[..] == &other.large_array[..] - } -} diff --git a/bindgen-tests/tests/expectations/tests/derive-partialeq-union_1_0.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-union_1_0.rs deleted file mode 100644 index f120f4fc12..0000000000 --- a/bindgen-tests/tests/expectations/tests/derive-partialeq-union_1_0.rs +++ /dev/null @@ -1,96 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -/// This should manually derive PartialEq. -#[repr(C)] -#[derive(Copy)] -pub struct ShouldDerivePartialEq { - pub a: __BindgenUnionField<[::std::os::raw::c_char; 150usize]>, - pub b: __BindgenUnionField<::std::os::raw::c_int>, - pub bindgen_union_field: [u32; 38usize], -} -#[test] -fn bindgen_test_layout_ShouldDerivePartialEq() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 152usize, - "Size of ShouldDerivePartialEq", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of ShouldDerivePartialEq", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: ShouldDerivePartialEq::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: ShouldDerivePartialEq::b", - ); -} -impl Clone for ShouldDerivePartialEq { - fn clone(&self) -> Self { - *self - } -} -impl Default for ShouldDerivePartialEq { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -impl ::std::cmp::PartialEq for ShouldDerivePartialEq { - fn eq(&self, other: &ShouldDerivePartialEq) -> bool { - &self.bindgen_union_field[..] == &other.bindgen_union_field[..] - } -} diff --git a/bindgen-tests/tests/expectations/tests/disable-nested-struct-naming.rs b/bindgen-tests/tests/expectations/tests/disable-nested-struct-naming.rs index 68c729b735..757e0481aa 100644 --- a/bindgen-tests/tests/expectations/tests/disable-nested-struct-naming.rs +++ b/bindgen-tests/tests/expectations/tests/disable-nested-struct-naming.rs @@ -117,6 +117,6 @@ const _: () = { "Offset of field: _bindgen_ty_1::anon2", ][::std::mem::offset_of!(_bindgen_ty_1, anon2) - 0usize]; }; -extern "C" { +unsafe extern "C" { pub static mut anon1: _bindgen_ty_1; } diff --git a/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs b/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs index 707c2d56bc..37139d3136 100644 --- a/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs +++ b/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,11 +126,28 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct WithBitfield { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub a: ::std::os::raw::c_uint, } @@ -100,7 +161,6 @@ impl WithBitfield { #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct WithBitfieldAndAttrPacked { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub a: ::std::os::raw::c_uint, } @@ -114,7 +174,6 @@ impl WithBitfieldAndAttrPacked { #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct WithBitfieldAndPacked { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub a: ::std::os::raw::c_uint, } diff --git a/bindgen-tests/tests/expectations/tests/duplicated-definition-count.rs b/bindgen-tests/tests/expectations/tests/duplicated-definition-count.rs index 85f28dcca6..86e1edbbf9 100644 --- a/bindgen-tests/tests/expectations/tests/duplicated-definition-count.rs +++ b/bindgen-tests/tests/expectations/tests/duplicated-definition-count.rs @@ -9,7 +9,7 @@ const _: () = { ["Size of BitStream"][::std::mem::size_of::() - 1usize]; ["Alignment of BitStream"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN9BitStream5WriteEPKcj"] pub fn BitStream_Write( this: *mut BitStream, @@ -17,7 +17,7 @@ extern "C" { numberOfBytes: ::std::os::raw::c_uint, ); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN9BitStream5WriteEPS_j"] pub fn BitStream_Write1( this: *mut BitStream, @@ -25,7 +25,7 @@ extern "C" { numberOfBits: ::std::os::raw::c_uint, ); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN9BitStream6Write1Ev"] pub fn BitStream_Write11(this: *mut BitStream); } diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_template.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_template.rs index 65f079bede..1f63a7893f 100644 --- a/bindgen-tests/tests/expectations/tests/dynamic_loading_template.rs +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_template.rs @@ -20,8 +20,8 @@ impl TestLib { L: Into<::libloading::Library>, { let __library = library.into(); - let foo = __library.get(b"foo\0").map(|sym| *sym); - let foo1 = __library.get(b"foo1\0").map(|sym| *sym); + let foo = __library.get(b"_Z3fooIiET_S0_\0").map(|sym| *sym); + let foo1 = __library.get(b"_Z3fooIfET_S0_\0").map(|sym| *sym); Ok(TestLib { __library, foo, foo1 }) } pub unsafe fn foo(&self, x: ::std::os::raw::c_int) -> ::std::os::raw::c_int { diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_allowlist.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_allowlist.rs index e65176b863..34ebe8d9a5 100644 --- a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_allowlist.rs +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_allowlist.rs @@ -27,9 +27,9 @@ impl TestLib { L: Into<::libloading::Library>, { let __library = library.into(); - let foo = __library.get(b"foo\0").map(|sym| *sym); - let baz = __library.get(b"baz\0").map(|sym| *sym); - let bazz = __library.get(b"bazz\0").map(|sym| *sym); + let foo = __library.get(b"_Z3fooPv\0").map(|sym| *sym); + let baz = __library.get(b"_Z3bazPv\0").map(|sym| *sym); + let bazz = __library.get(b"_Z4bazziz\0").map(|sym| *sym); Ok(TestLib { __library, foo, diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_blocklist.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_blocklist.rs index 776da1ca5f..8c86674f7a 100644 --- a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_blocklist.rs +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_blocklist.rs @@ -10,15 +10,15 @@ const _: () = { ["Alignment of X"][::std::mem::align_of::() - 4usize]; ["Offset of field: X::_x"][::std::mem::offset_of!(X, _x) - 0usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1X13some_functionEv"] pub fn X_some_function(this: *mut X); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1X19some_other_functionEv"] pub fn X_some_other_function(this: *mut X); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1XC1Ei"] pub fn X_X(this: *mut X, x: ::std::os::raw::c_int); } @@ -62,8 +62,8 @@ impl TestLib { L: Into<::libloading::Library>, { let __library = library.into(); - let foo = __library.get(b"foo\0").map(|sym| *sym); - let bar = __library.get(b"bar\0").map(|sym| *sym); + let foo = __library.get(b"_Z3fooPv\0").map(|sym| *sym); + let bar = __library.get(b"_Z3barPv\0").map(|sym| *sym); Ok(TestLib { __library, foo, bar }) } pub unsafe fn foo(&self, x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int { diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs index 93c636ebff..65ff2b2f72 100644 --- a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs @@ -10,15 +10,15 @@ const _: () = { ["Alignment of A"][::std::mem::align_of::() - 4usize]; ["Offset of field: A::_x"][::std::mem::offset_of!(A, _x) - 0usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1A13some_functionEv"] pub fn A_some_function(this: *mut A); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1A19some_other_functionEv"] pub fn A_some_other_function(this: *mut A); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1AC1Ei"] pub fn A_A(this: *mut A, x: ::std::os::raw::c_int); } @@ -59,8 +59,8 @@ impl TestLib { L: Into<::libloading::Library>, { let __library = library.into(); - let foo = __library.get(b"foo\0").map(|sym| *sym); - let bar = __library.get(b"bar\0").map(|sym| *sym); + let foo = __library.get(b"_Z3fooPv\0").map(|sym| *sym); + let bar = __library.get(b"_Z3barv\0").map(|sym| *sym); Ok(TestLib { __library, foo, bar }) } pub unsafe fn foo(&self, x: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int { diff --git a/bindgen-tests/tests/expectations/tests/elaborated.rs b/bindgen-tests/tests/expectations/tests/elaborated.rs index 80bf30f89a..81c0733089 100644 --- a/bindgen-tests/tests/expectations/tests/elaborated.rs +++ b/bindgen-tests/tests/expectations/tests/elaborated.rs @@ -1,6 +1,6 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub type whatever_whatever_t = ::std::os::raw::c_int; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z9somethingPKi"] pub fn something(wat: *const whatever_whatever_t); } diff --git a/bindgen-tests/tests/expectations/tests/empty-enum.rs b/bindgen-tests/tests/expectations/tests/empty-enum.rs index fda6f581df..d19aa41845 100644 --- a/bindgen-tests/tests/expectations/tests/empty-enum.rs +++ b/bindgen-tests/tests/expectations/tests/empty-enum.rs @@ -6,6 +6,8 @@ pub enum EmptyRustified { __bindgen_cannot_repr_c_on_empty_enum = 0, } pub mod EmptyModule { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; } #[repr(i8)] @@ -15,6 +17,8 @@ pub enum EmptyClassRustified { } pub type EmptyClassConstified = ::std::os::raw::c_char; pub mod EmptyClassModule { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_char; } #[repr(i8)] @@ -24,5 +28,7 @@ pub enum ForwardClassRustified { } pub type ForwardClassConstified = ::std::os::raw::c_char; pub mod ForwardClassModule { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_char; } diff --git a/bindgen-tests/tests/expectations/tests/enum-default-bitfield.rs b/bindgen-tests/tests/expectations/tests/enum-default-bitfield.rs index 58b8bf092f..dda688617c 100644 --- a/bindgen-tests/tests/expectations/tests/enum-default-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/enum-default-bitfield.rs @@ -52,8 +52,6 @@ impl Default for foo { } impl Foo { pub const Bar: Foo = Foo(0); -} -impl Foo { pub const Qux: Foo = Foo(1); } impl ::std::ops::BitOr for Foo { @@ -86,14 +84,14 @@ impl ::std::ops::BitAndAssign for Foo { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Foo(pub ::std::os::raw::c_uint); pub mod Neg { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_int; pub const MinusOne: Type = -1; pub const One: Type = 1; } impl NoDebug { pub const NoDebug1: NoDebug = NoDebug(0); -} -impl NoDebug { pub const NoDebug2: NoDebug = NoDebug(1); } impl ::std::ops::BitOr for NoDebug { @@ -128,8 +126,6 @@ impl ::std::ops::BitAndAssign for NoDebug { pub struct NoDebug(pub ::std::os::raw::c_uint); impl Debug { pub const Debug1: Debug = Debug(0); -} -impl Debug { pub const Debug2: Debug = Debug(1); } impl ::std::ops::BitOr for Debug { diff --git a/bindgen-tests/tests/expectations/tests/enum-default-consts.rs b/bindgen-tests/tests/expectations/tests/enum-default-consts.rs index af51864c2c..1432182310 100644 --- a/bindgen-tests/tests/expectations/tests/enum-default-consts.rs +++ b/bindgen-tests/tests/expectations/tests/enum-default-consts.rs @@ -26,6 +26,8 @@ pub const Foo_Bar: Foo = 0; pub const Foo_Qux: Foo = 1; pub type Foo = ::std::os::raw::c_uint; pub mod Neg { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_int; pub const MinusOne: Type = -1; pub const One: Type = 1; diff --git a/bindgen-tests/tests/expectations/tests/enum-default-module.rs b/bindgen-tests/tests/expectations/tests/enum-default-module.rs index cc09d49425..23fbd22c6e 100644 --- a/bindgen-tests/tests/expectations/tests/enum-default-module.rs +++ b/bindgen-tests/tests/expectations/tests/enum-default-module.rs @@ -5,6 +5,8 @@ pub struct foo { pub member: foo__bindgen_ty_1::Type, } pub mod foo__bindgen_ty_1 { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const FOO_A: Type = 0; pub const FOO_B: Type = 1; @@ -25,22 +27,30 @@ impl Default for foo { } } pub mod Foo { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const Bar: Type = 0; pub const Qux: Type = 1; } pub mod Neg { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_int; pub const MinusOne: Type = -1; pub const One: Type = 1; } pub mod NoDebug { + #[allow(unused_imports)] + use super::*; ///
pub type Type = ::std::os::raw::c_uint; pub const NoDebug1: Type = 0; pub const NoDebug2: Type = 1; } pub mod Debug { + #[allow(unused_imports)] + use super::*; ///
pub type Type = ::std::os::raw::c_uint; pub const Debug1: Type = 0; diff --git a/bindgen-tests/tests/expectations/tests/enum-default-rust.rs b/bindgen-tests/tests/expectations/tests/enum-default-rust.rs index f9a99166de..59901a78ac 100644 --- a/bindgen-tests/tests/expectations/tests/enum-default-rust.rs +++ b/bindgen-tests/tests/expectations/tests/enum-default-rust.rs @@ -34,6 +34,8 @@ pub enum Foo { Qux = 1, } pub mod Neg { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_int; pub const MinusOne: Type = -1; pub const One: Type = 1; diff --git a/bindgen-tests/tests/expectations/tests/enum-doc-bitfield.rs b/bindgen-tests/tests/expectations/tests/enum-doc-bitfield.rs index ba73a8ea3e..33eec3e44f 100644 --- a/bindgen-tests/tests/expectations/tests/enum-doc-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/enum-doc-bitfield.rs @@ -2,24 +2,14 @@ impl B { /// Document field with three slashes pub const VAR_A: B = B(0); -} -impl B { /// Document field with preceding star pub const VAR_B: B = B(1); -} -impl B { /// Document field with preceding exclamation pub const VAR_C: B = B(2); -} -impl B { ///< Document field with following star pub const VAR_D: B = B(3); -} -impl B { ///< Document field with following exclamation pub const VAR_E: B = B(4); -} -impl B { /** Document field with preceding star, with a loong long multiline comment. diff --git a/bindgen-tests/tests/expectations/tests/enum-doc-mod.rs b/bindgen-tests/tests/expectations/tests/enum-doc-mod.rs index 2b18b35df0..580d8165ac 100644 --- a/bindgen-tests/tests/expectations/tests/enum-doc-mod.rs +++ b/bindgen-tests/tests/expectations/tests/enum-doc-mod.rs @@ -1,5 +1,7 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub mod B { + #[allow(unused_imports)] + use super::*; /// Document enum pub type Type = ::std::os::raw::c_uint; /// Document field with three slashes diff --git a/bindgen-tests/tests/expectations/tests/enum-doc-rusty-non-exhaustive.rs b/bindgen-tests/tests/expectations/tests/enum-doc-rusty-non-exhaustive.rs new file mode 100644 index 0000000000..1d09466119 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/enum-doc-rusty-non-exhaustive.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(u32)] +#[non_exhaustive] +/// Document enum +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum B { + /// Document field with three slashes + VAR_A = 0, + /// Document field with preceding star + VAR_B = 1, + /// Document field with preceding exclamation + VAR_C = 2, + ///< Document field with following star + VAR_D = 3, + ///< Document field with following exclamation + VAR_E = 4, + /** Document field with preceding star, with a loong long multiline + comment. + + Very interesting documentation, definitely.*/ + VAR_F = 5, +} diff --git a/bindgen-tests/tests/expectations/tests/enum-no-debug-rust.rs b/bindgen-tests/tests/expectations/tests/enum-no-debug-rust.rs index b728dfc898..643577e1e3 100644 --- a/bindgen-tests/tests/expectations/tests/enum-no-debug-rust.rs +++ b/bindgen-tests/tests/expectations/tests/enum-no-debug-rust.rs @@ -34,6 +34,8 @@ pub enum Foo { Qux = 1, } pub mod Neg { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_int; pub const MinusOne: Type = -1; pub const One: Type = 1; diff --git a/bindgen-tests/tests/expectations/tests/enum_and_vtable_mangling.rs b/bindgen-tests/tests/expectations/tests/enum_and_vtable_mangling.rs index 18e1ad8e36..0a7e16d6dd 100644 --- a/bindgen-tests/tests/expectations/tests/enum_and_vtable_mangling.rs +++ b/bindgen-tests/tests/expectations/tests/enum_and_vtable_mangling.rs @@ -32,7 +32,7 @@ impl Default for C { } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1C5matchEv"] pub fn C_match(this: *mut ::std::os::raw::c_void); } diff --git a/bindgen-tests/tests/expectations/tests/extern-const-struct.rs b/bindgen-tests/tests/expectations/tests/extern-const-struct.rs index c449e1a019..7085bef5c8 100644 --- a/bindgen-tests/tests/expectations/tests/extern-const-struct.rs +++ b/bindgen-tests/tests/expectations/tests/extern-const-struct.rs @@ -1,21 +1,15 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct nsFoo { pub details: [f32; 400usize], } -#[test] -fn bindgen_test_layout_nsFoo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 1600usize, "Size of nsFoo"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of nsFoo"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).details) as usize - ptr as usize }, - 0usize, - "Offset of field: nsFoo::details", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of nsFoo"][::std::mem::size_of::() - 1600usize]; + ["Alignment of nsFoo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: nsFoo::details"][::std::mem::offset_of!(nsFoo, details) - 0usize]; +}; impl Default for nsFoo { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -25,6 +19,6 @@ impl Default for nsFoo { } } } -extern "C" { +unsafe extern "C" { pub static gDetails: nsFoo; } diff --git a/bindgen-tests/tests/expectations/tests/extern-fn-block-attrs-many.rs b/bindgen-tests/tests/expectations/tests/extern-fn-block-attrs-many.rs new file mode 100644 index 0000000000..5aa9e45ec2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/extern-fn-block-attrs-many.rs @@ -0,0 +1,6 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[allow(dead_code)] +#[cfg_attr(not(windows), link(wasm_import_module = "test-module"))] +unsafe extern "C" { + pub fn test_function(); +} diff --git a/bindgen-tests/tests/expectations/tests/extern-fn-block-attrs-wasm.rs b/bindgen-tests/tests/expectations/tests/extern-fn-block-attrs-wasm.rs new file mode 100644 index 0000000000..388594b27e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/extern-fn-block-attrs-wasm.rs @@ -0,0 +1,6 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[link(wasm_import_module = "test-module")] +#[allow(dead_code)] +unsafe extern "C" { + pub fn test_function(); +} diff --git a/bindgen-tests/tests/expectations/tests/extern-fn-block-attrs.rs b/bindgen-tests/tests/expectations/tests/extern-fn-block-attrs.rs new file mode 100644 index 0000000000..657cec106a --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/extern-fn-block-attrs.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[allow(dead_code)] +unsafe extern "C" { + pub fn test_function(); +} diff --git a/bindgen-tests/tests/expectations/tests/extern_blocks_post_1_82.rs b/bindgen-tests/tests/expectations/tests/extern_blocks_post_1_82.rs new file mode 100644 index 0000000000..a322df78ce --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/extern_blocks_post_1_82.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn cool_function(i: ::std::os::raw::c_int, c: ::std::os::raw::c_char); +} +unsafe extern "C" { + pub static mut cool_static: ::std::os::raw::c_int; +} diff --git a/bindgen-tests/tests/expectations/tests/extern_blocks_pre_1_82.rs b/bindgen-tests/tests/expectations/tests/extern_blocks_pre_1_82.rs new file mode 100644 index 0000000000..a322df78ce --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/extern_blocks_pre_1_82.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +unsafe extern "C" { + pub fn cool_function(i: ::std::os::raw::c_int, c: ::std::os::raw::c_char); +} +unsafe extern "C" { + pub static mut cool_static: ::std::os::raw::c_int; +} diff --git a/bindgen-tests/tests/expectations/tests/field-visibility-callback.rs b/bindgen-tests/tests/expectations/tests/field-visibility-callback.rs index 9be373e5a7..99ca3d4b9b 100644 --- a/bindgen-tests/tests/expectations/tests/field-visibility-callback.rs +++ b/bindgen-tests/tests/expectations/tests/field-visibility-callback.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,13 +126,30 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct my_struct { pub a: ::std::os::raw::c_int, private_b: ::std::os::raw::c_int, - _bitfield_align_1: [u8; 0], _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, __bindgen_padding_0: [u8; 3usize], } @@ -114,6 +175,31 @@ impl my_struct { } } #[inline] + pub unsafe fn c_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_c_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] fn private_d(&self) -> ::std::os::raw::c_int { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } } @@ -125,6 +211,31 @@ impl my_struct { } } #[inline] + unsafe fn private_d_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) + as u32, + ) + } + } + #[inline] + unsafe fn set_private_d_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] fn new_bitfield_1( c: ::std::os::raw::c_int, private_d: ::std::os::raw::c_int, diff --git a/bindgen-tests/tests/expectations/tests/field-visibility.rs b/bindgen-tests/tests/expectations/tests/field-visibility.rs index 2ad5dc838e..13a1d9a543 100644 --- a/bindgen-tests/tests/expectations/tests/field-visibility.rs +++ b/bindgen-tests/tests/expectations/tests/field-visibility.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,12 +126,29 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] -#[repr(align(4))] #[derive(Debug, Default, Copy, Clone)] pub struct my_struct1 { - _bitfield_align_1: [u8; 0], + pub _bindgen_align: [u32; 0], _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, __bindgen_padding_0: [u8; 3usize], } @@ -109,6 +170,31 @@ impl my_struct1 { } } #[inline] + unsafe fn a_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) + as u32, + ) + } + } + #[inline] + unsafe fn set_a_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] fn new_bitfield_1(a: ::std::os::raw::c_int) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); __bindgen_bitfield_unit @@ -124,10 +210,9 @@ impl my_struct1 { } } #[repr(C)] -#[repr(align(4))] #[derive(Debug, Default, Copy, Clone)] pub struct my_struct2 { - pub _bitfield_align_1: [u8; 0], + pub _bindgen_align: [u32; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub __bindgen_padding_0: [u8; 3usize], } @@ -149,6 +234,31 @@ impl my_struct2 { } } #[inline] + pub unsafe fn a_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_a_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( a: ::std::os::raw::c_int, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { diff --git a/bindgen-tests/tests/expectations/tests/fit-macro-constant-types-signed.rs b/bindgen-tests/tests/expectations/tests/fit-macro-constant-types-signed.rs index 0602f7714a..d4ad5e0fcc 100644 --- a/bindgen-tests/tests/expectations/tests/fit-macro-constant-types-signed.rs +++ b/bindgen-tests/tests/expectations/tests/fit-macro-constant-types-signed.rs @@ -30,7 +30,7 @@ pub const MIN_U32_Minus1: i8 = -1; pub const MIN_I32_Minus1: i64 = -2147483649; pub const LONG12: i64 = 123456789012; pub const LONG_12: i64 = -123456789012; -extern "C" { +unsafe extern "C" { pub fn foo( arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int, @@ -40,7 +40,7 @@ extern "C" { arg6: ::std::os::raw::c_schar, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn bar( arg1: ::std::os::raw::c_long, arg2: ::std::os::raw::c_longlong, diff --git a/bindgen-tests/tests/expectations/tests/fit-macro-constant-types.rs b/bindgen-tests/tests/expectations/tests/fit-macro-constant-types.rs index f5d2a56ff2..5542a645da 100644 --- a/bindgen-tests/tests/expectations/tests/fit-macro-constant-types.rs +++ b/bindgen-tests/tests/expectations/tests/fit-macro-constant-types.rs @@ -30,7 +30,7 @@ pub const MIN_U32_Minus1: i8 = -1; pub const MIN_I32_Minus1: i64 = -2147483649; pub const LONG12: u64 = 123456789012; pub const LONG_12: i64 = -123456789012; -extern "C" { +unsafe extern "C" { pub fn foo( arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int, @@ -40,7 +40,7 @@ extern "C" { arg6: ::std::os::raw::c_schar, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn bar( arg1: ::std::os::raw::c_long, arg2: ::std::os::raw::c_longlong, diff --git a/bindgen-tests/tests/expectations/tests/float16.rs b/bindgen-tests/tests/expectations/tests/float16.rs index 1804d1007a..2066b71801 100644 --- a/bindgen-tests/tests/expectations/tests/float16.rs +++ b/bindgen-tests/tests/expectations/tests/float16.rs @@ -2,7 +2,7 @@ #[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] #[repr(transparent)] pub struct __BindgenFloat16(pub u16); -extern "C" { +unsafe extern "C" { pub static mut global: __BindgenFloat16; } #[repr(C)] diff --git a/bindgen-tests/tests/expectations/tests/forward_declared_complex_types.rs b/bindgen-tests/tests/expectations/tests/forward_declared_complex_types.rs index 2ba1071c8e..79554d58e4 100644 --- a/bindgen-tests/tests/expectations/tests/forward_declared_complex_types.rs +++ b/bindgen-tests/tests/expectations/tests/forward_declared_complex_types.rs @@ -34,7 +34,7 @@ impl Default for Bar { } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z10baz_structP3Foo"] pub fn baz_struct(f: *mut Foo); } @@ -43,7 +43,7 @@ extern "C" { pub struct Union { _unused: [u8; 0], } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z9baz_unionP5Union"] pub fn baz_union(u: *mut Union); } @@ -52,7 +52,7 @@ extern "C" { pub struct Quux { _unused: [u8; 0], } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z9baz_classP4Quux"] pub fn baz_class(q: *mut Quux); } diff --git a/bindgen-tests/tests/expectations/tests/forward_declared_complex_types_1_0.rs b/bindgen-tests/tests/expectations/tests/forward_declared_complex_types_1_0.rs deleted file mode 100644 index e891a6b01b..0000000000 --- a/bindgen-tests/tests/expectations/tests/forward_declared_complex_types_1_0.rs +++ /dev/null @@ -1,89 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -#[derive(Debug, Default, Copy)] -pub struct Foo_empty { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Foo_empty() { - assert_eq!(::std::mem::size_of::(), 1usize, "Size of Foo_empty"); - assert_eq!(::std::mem::align_of::(), 1usize, "Alignment of Foo_empty"); -} -impl Clone for Foo_empty { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Copy)] -pub struct Foo { - _unused: [u8; 0], -} -impl Clone for Foo { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Copy)] -pub struct Bar { - pub f: *mut Foo, -} -#[test] -fn bindgen_test_layout_Bar() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of Bar"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of Bar"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).f) as usize - ptr as usize }, - 0usize, - "Offset of field: Bar::f", - ); -} -impl Clone for Bar { - fn clone(&self) -> Self { - *self - } -} -impl Default for Bar { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -extern "C" { - #[link_name = "\u{1}_Z10baz_structP3Foo"] - pub fn baz_struct(f: *mut Foo); -} -#[repr(C)] -#[derive(Debug, Copy)] -pub struct Union { - _unused: [u8; 0], -} -impl Clone for Union { - fn clone(&self) -> Self { - *self - } -} -extern "C" { - #[link_name = "\u{1}_Z9baz_unionP5Union"] - pub fn baz_union(u: *mut Union); -} -#[repr(C)] -#[derive(Debug, Copy)] -pub struct Quux { - _unused: [u8; 0], -} -impl Clone for Quux { - fn clone(&self) -> Self { - *self - } -} -extern "C" { - #[link_name = "\u{1}_Z9baz_classP4Quux"] - pub fn baz_class(q: *mut Quux); -} diff --git a/bindgen-tests/tests/expectations/tests/func_ptr.rs b/bindgen-tests/tests/expectations/tests/func_ptr.rs index 4e9c5b131d..b91bdba872 100644 --- a/bindgen-tests/tests/expectations/tests/func_ptr.rs +++ b/bindgen-tests/tests/expectations/tests/func_ptr.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub static mut foo: ::std::option::Option< unsafe extern "C" fn( x: ::std::os::raw::c_int, diff --git a/bindgen-tests/tests/expectations/tests/func_ptr_return_type.rs b/bindgen-tests/tests/expectations/tests/func_ptr_return_type.rs index c1c890249f..504eefdfb1 100644 --- a/bindgen-tests/tests/expectations/tests/func_ptr_return_type.rs +++ b/bindgen-tests/tests/expectations/tests/func_ptr_return_type.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn func() -> ::std::option::Option< unsafe extern "C" fn( arg1: ::std::os::raw::c_int, diff --git a/bindgen-tests/tests/expectations/tests/func_return_must_use.rs b/bindgen-tests/tests/expectations/tests/func_return_must_use.rs index bc9deb0818..904c71cbe3 100644 --- a/bindgen-tests/tests/expectations/tests/func_return_must_use.rs +++ b/bindgen-tests/tests/expectations/tests/func_return_must_use.rs @@ -1,6 +1,6 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub type MustUseInt = ::std::os::raw::c_int; -extern "C" { +unsafe extern "C" { #[must_use] pub fn return_int() -> MustUseInt; } @@ -10,17 +10,17 @@ extern "C" { pub struct MustUseStruct { _unused: [u8; 0], } -extern "C" { +unsafe extern "C" { #[must_use] pub fn return_struct() -> MustUseStruct; } ///
pub type AnnotatedInt = ::std::os::raw::c_int; -extern "C" { +unsafe extern "C" { #[must_use] pub fn return_annotated_int() -> AnnotatedInt; } -extern "C" { +unsafe extern "C" { pub fn return_plain_int() -> ::std::os::raw::c_int; } ///
@@ -33,7 +33,7 @@ const _: () = { ["Size of AnnotatedStruct"][::std::mem::size_of::() - 0usize]; ["Alignment of AnnotatedStruct"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[must_use] pub fn return_annotated_struct() -> AnnotatedStruct; } @@ -47,10 +47,10 @@ const _: () = { }; ///
pub type TypedefPlainStruct = PlainStruct; -extern "C" { +unsafe extern "C" { pub fn return_plain_struct() -> PlainStruct; } -extern "C" { +unsafe extern "C" { #[must_use] pub fn return_typedef_struct() -> TypedefPlainStruct; } diff --git a/bindgen-tests/tests/expectations/tests/func_with_array_arg.rs b/bindgen-tests/tests/expectations/tests/func_with_array_arg.rs index e41cb2ce44..20bdc4ac27 100644 --- a/bindgen-tests/tests/expectations/tests/func_with_array_arg.rs +++ b/bindgen-tests/tests/expectations/tests/func_with_array_arg.rs @@ -1,4 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn f(x: *mut ::std::os::raw::c_int); } diff --git a/bindgen-tests/tests/expectations/tests/func_with_func_ptr_arg.rs b/bindgen-tests/tests/expectations/tests/func_with_func_ptr_arg.rs index af8a3fc68c..56cf40fb59 100644 --- a/bindgen-tests/tests/expectations/tests/func_with_func_ptr_arg.rs +++ b/bindgen-tests/tests/expectations/tests/func_with_func_ptr_arg.rs @@ -1,8 +1,8 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn foo(bar: ::std::option::Option); } -extern "C" { +unsafe extern "C" { pub fn bar( one: ::std::option::Option< unsafe extern "C" fn(a: ::std::os::raw::c_int, b: ::std::os::raw::c_int), diff --git a/bindgen-tests/tests/expectations/tests/gen-constructors.rs b/bindgen-tests/tests/expectations/tests/gen-constructors.rs index c1a8b676fd..80e6a25d70 100644 --- a/bindgen-tests/tests/expectations/tests/gen-constructors.rs +++ b/bindgen-tests/tests/expectations/tests/gen-constructors.rs @@ -9,7 +9,7 @@ const _: () = { ["Size of Foo"][::std::mem::size_of::() - 1usize]; ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3FooC1Ei"] pub fn Foo_Foo(this: *mut Foo, a: ::std::os::raw::c_int); } diff --git a/bindgen-tests/tests/expectations/tests/gen-destructors.rs b/bindgen-tests/tests/expectations/tests/gen-destructors.rs index f3dc655f08..c860c9985f 100644 --- a/bindgen-tests/tests/expectations/tests/gen-destructors.rs +++ b/bindgen-tests/tests/expectations/tests/gen-destructors.rs @@ -10,7 +10,7 @@ const _: () = { ["Alignment of Foo"][::std::mem::align_of::() - 4usize]; ["Offset of field: Foo::bar"][::std::mem::offset_of!(Foo, bar) - 0usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3FooD1Ev"] pub fn Foo_Foo_destructor(this: *mut Foo); } diff --git a/bindgen-tests/tests/expectations/tests/generate-inline.rs b/bindgen-tests/tests/expectations/tests/generate-inline.rs index 1d60a98570..c100f3936c 100644 --- a/bindgen-tests/tests/expectations/tests/generate-inline.rs +++ b/bindgen-tests/tests/expectations/tests/generate-inline.rs @@ -9,7 +9,7 @@ const _: () = { ["Size of Foo"][::std::mem::size_of::() - 1usize]; ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo3barEv"] pub fn Foo_bar() -> ::std::os::raw::c_int; } @@ -19,7 +19,7 @@ impl Foo { Foo_bar() } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z3foov"] pub fn foo() -> ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns_aarch64_linux.c b/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns_aarch64_linux.c new file mode 100644 index 0000000000..a4269d8505 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns_aarch64_linux.c @@ -0,0 +1,14 @@ +#include "tests/headers/wrap-static-fns.h" + +// Static wrappers + +int foo__extern(void) { return foo(); } +int bar__extern(void) { return bar(); } +int takes_ptr__extern(int *arg) { return takes_ptr(arg); } +int takes_fn_ptr__extern(int (*f) (int)) { return takes_fn_ptr(f); } +int takes_fn__extern(int (f) (int)) { return takes_fn(f); } +int takes_alias__extern(func f) { return takes_alias(f); } +int takes_qualified__extern(const int *const *arg) { return takes_qualified(arg); } +enum foo takes_enum__extern(const enum foo f) { return takes_enum(f); } +void nevermore__extern(void) { nevermore(); } +int takes_fn_with_no_args__extern(int (f) (void)) { return takes_fn_with_no_args(f); } diff --git a/bindgen-tests/tests/expectations/tests/i128.rs b/bindgen-tests/tests/expectations/tests/i128.rs index 87459b5e75..e29db491fe 100644 --- a/bindgen-tests/tests/expectations/tests/i128.rs +++ b/bindgen-tests/tests/expectations/tests/i128.rs @@ -6,20 +6,12 @@ pub struct foo { pub my_signed: i128, pub my_unsigned: u128, } -#[test] -fn bindgen_test_layout_foo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 32usize, "Size of foo"); - assert_eq!(::std::mem::align_of::(), 16usize, "Alignment of foo"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).my_signed) as usize - ptr as usize }, - 0usize, - "Offset of field: foo::my_signed", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).my_unsigned) as usize - ptr as usize }, - 16usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 32usize]; + ["Alignment of foo"][::std::mem::align_of::() - 16usize]; + ["Offset of field: foo::my_signed"][::std::mem::offset_of!(foo, my_signed) - 0usize]; + [ "Offset of field: foo::my_unsigned", - ); -} + ][::std::mem::offset_of!(foo, my_unsigned) - 16usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs b/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs index 148f4ffa41..a90fe54bf3 100644 --- a/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs +++ b/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,6 +126,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Default)] @@ -116,7 +178,6 @@ impl ::std::fmt::Debug for __IncompleteArrayField { #[repr(C)] #[derive(Debug)] pub struct foo { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub b: __IncompleteArrayField<*mut ::std::os::raw::c_void>, } @@ -148,6 +209,30 @@ impl foo { } } #[inline] + pub unsafe fn a_raw(this: *const Self) -> ::std::os::raw::c_char { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_a_raw(this: *mut Self, val: ::std::os::raw::c_char) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( a: ::std::os::raw::c_char, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { diff --git a/bindgen-tests/tests/expectations/tests/infinite-macro.rs b/bindgen-tests/tests/expectations/tests/infinite-macro.rs index f19879fb17..cf2b32f0ed 100644 --- a/bindgen-tests/tests/expectations/tests/infinite-macro.rs +++ b/bindgen-tests/tests/expectations/tests/infinite-macro.rs @@ -1,3 +1,7 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -pub const INFINITY: f64 = f64::INFINITY; -pub const NAN: f64 = f64::NAN; +pub const INFINITY: f64 = f64::INFINITY as _; +pub const NEG_INFINITY: f64 = f64::NEG_INFINITY as _; +pub const NAN: f64 = f64::NAN as _; +pub const F32_INFINITY: f32 = f64::INFINITY as _; +pub const F32_NEG_INFINITY: f32 = f64::NEG_INFINITY as _; +pub const F32_NAN: f32 = f64::NAN as _; diff --git a/bindgen-tests/tests/expectations/tests/inline_namespace_macro.rs b/bindgen-tests/tests/expectations/tests/inline_namespace_macro.rs new file mode 100644 index 0000000000..99ca607d2f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/inline_namespace_macro.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub mod root { + #[allow(unused_imports)] + use self::super::root; + pub mod repro { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct duration { + pub _address: u8, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of duration"][::std::mem::size_of::() - 1usize]; + ["Alignment of duration"][::std::mem::align_of::() - 1usize]; + }; + } +} diff --git a/bindgen-tests/tests/expectations/tests/inner-typedef-gh422.rs b/bindgen-tests/tests/expectations/tests/inner-typedef-gh422.rs index 69d2151bbb..16b1eb48ea 100644 --- a/bindgen-tests/tests/expectations/tests/inner-typedef-gh422.rs +++ b/bindgen-tests/tests/expectations/tests/inner-typedef-gh422.rs @@ -20,7 +20,7 @@ impl Default for Foo_InnerType { } } pub type Bar = InnerType; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z4funcv"] pub fn func() -> Bar; } diff --git a/bindgen-tests/tests/expectations/tests/inner_const.rs b/bindgen-tests/tests/expectations/tests/inner_const.rs index f8f0c45a29..ad8af7ce35 100644 --- a/bindgen-tests/tests/expectations/tests/inner_const.rs +++ b/bindgen-tests/tests/expectations/tests/inner_const.rs @@ -4,11 +4,11 @@ pub struct Foo { pub bar: ::std::os::raw::c_int, } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo3BOOE"] pub static mut Foo_BOO: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo8whateverE"] pub static mut Foo_whatever: Foo; } diff --git a/bindgen-tests/tests/expectations/tests/issue-1034.rs b/bindgen-tests/tests/expectations/tests/issue-1034.rs index 17450a1346..90cc768a94 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1034.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1034.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,11 +126,28 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct S2 { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] diff --git a/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs b/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs index 5bdf08d992..50e9283b5a 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,11 +126,28 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct S1 { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] diff --git a/bindgen-tests/tests/expectations/tests/issue-1118-using-forward-decl.rs b/bindgen-tests/tests/expectations/tests/issue-1118-using-forward-decl.rs index 7356aa679a..7df1cdb741 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1118-using-forward-decl.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1118-using-forward-decl.rs @@ -58,7 +58,7 @@ impl Default for nsIContent { } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z35Gecko_GetAnonymousContentForElementv"] pub fn Gecko_GetAnonymousContentForElement() -> *mut nsTArray; } diff --git a/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-bitfield-enum.rs b/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-bitfield-enum.rs index 7bbcb0d50b..5aaff691b4 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-bitfield-enum.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-bitfield-enum.rs @@ -1,11 +1,7 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] impl MyDupeEnum { pub const A: MyDupeEnum = MyDupeEnum(0); -} -impl MyDupeEnum { pub const A_alias: MyDupeEnum = MyDupeEnum(0); -} -impl MyDupeEnum { pub const B: MyDupeEnum = MyDupeEnum(1); } impl ::std::ops::BitOr for MyDupeEnum { @@ -39,11 +35,7 @@ impl ::std::ops::BitAndAssign for MyDupeEnum { pub struct MyDupeEnum(pub ::std::os::raw::c_uint); impl MyOtherDupeEnum { pub const C: MyOtherDupeEnum = MyOtherDupeEnum(0); -} -impl MyOtherDupeEnum { pub const C_alias: MyOtherDupeEnum = MyOtherDupeEnum(0); -} -impl MyOtherDupeEnum { pub const D: MyOtherDupeEnum = MyOtherDupeEnum(1); } impl ::std::ops::BitOr for MyOtherDupeEnum { diff --git a/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-const-mod-bitfield-enum.rs b/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-const-mod-bitfield-enum.rs index 76c1de0b1c..a69d005623 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-const-mod-bitfield-enum.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-const-mod-bitfield-enum.rs @@ -1,11 +1,15 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub mod MyDupeEnum { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const A: Type = 0; pub const A_alias: Type = 0; pub const B: Type = 1; } pub mod MyOtherDupeEnum { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const C: Type = 0; pub const C_alias: Type = 0; diff --git a/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-const-mod-enum.rs b/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-const-mod-enum.rs index 76c1de0b1c..a69d005623 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-const-mod-enum.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1198-alias-rust-const-mod-enum.rs @@ -1,11 +1,15 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub mod MyDupeEnum { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const A: Type = 0; pub const A_alias: Type = 0; pub const B: Type = 1; } pub mod MyOtherDupeEnum { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const C: Type = 0; pub const C_alias: Type = 0; diff --git a/bindgen-tests/tests/expectations/tests/issue-1216-variadic-member.rs b/bindgen-tests/tests/expectations/tests/issue-1216-variadic-member.rs index e3fe803654..7c562437e4 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1216-variadic-member.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1216-variadic-member.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn f(a: ::std::os::raw::c_int, ...); } #[repr(C)] diff --git a/bindgen-tests/tests/expectations/tests/issue-1291.rs b/bindgen-tests/tests/expectations/tests/issue-1291.rs index 190e899d7f..3c3fab3704 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1291.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1291.rs @@ -19,85 +19,35 @@ pub struct RTCRay { pub primID: ::std::os::raw::c_uint, pub instID: ::std::os::raw::c_uint, } -#[test] -fn bindgen_test_layout_RTCRay() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 96usize, "Size of RTCRay"); - assert_eq!(::std::mem::align_of::(), 16usize, "Alignment of RTCRay"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).org) as usize - ptr as usize }, - 0usize, - "Offset of field: RTCRay::org", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).align0) as usize - ptr as usize }, - 12usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of RTCRay"][::std::mem::size_of::() - 96usize]; + ["Alignment of RTCRay"][::std::mem::align_of::() - 16usize]; + ["Offset of field: RTCRay::org"][::std::mem::offset_of!(RTCRay, org) - 0usize]; + [ "Offset of field: RTCRay::align0", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dir) as usize - ptr as usize }, - 16usize, - "Offset of field: RTCRay::dir", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).align1) as usize - ptr as usize }, - 28usize, + ][::std::mem::offset_of!(RTCRay, align0) - 12usize]; + ["Offset of field: RTCRay::dir"][::std::mem::offset_of!(RTCRay, dir) - 16usize]; + [ "Offset of field: RTCRay::align1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tnear) as usize - ptr as usize }, - 32usize, - "Offset of field: RTCRay::tnear", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tfar) as usize - ptr as usize }, - 36usize, - "Offset of field: RTCRay::tfar", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).time) as usize - ptr as usize }, - 40usize, - "Offset of field: RTCRay::time", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mask) as usize - ptr as usize }, - 44usize, - "Offset of field: RTCRay::mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).Ng) as usize - ptr as usize }, - 48usize, - "Offset of field: RTCRay::Ng", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).align2) as usize - ptr as usize }, - 60usize, + ][::std::mem::offset_of!(RTCRay, align1) - 28usize]; + ["Offset of field: RTCRay::tnear"][::std::mem::offset_of!(RTCRay, tnear) - 32usize]; + ["Offset of field: RTCRay::tfar"][::std::mem::offset_of!(RTCRay, tfar) - 36usize]; + ["Offset of field: RTCRay::time"][::std::mem::offset_of!(RTCRay, time) - 40usize]; + ["Offset of field: RTCRay::mask"][::std::mem::offset_of!(RTCRay, mask) - 44usize]; + ["Offset of field: RTCRay::Ng"][::std::mem::offset_of!(RTCRay, Ng) - 48usize]; + [ "Offset of field: RTCRay::align2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).u) as usize - ptr as usize }, - 64usize, - "Offset of field: RTCRay::u", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).v) as usize - ptr as usize }, - 68usize, - "Offset of field: RTCRay::v", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).geomID) as usize - ptr as usize }, - 72usize, + ][::std::mem::offset_of!(RTCRay, align2) - 60usize]; + ["Offset of field: RTCRay::u"][::std::mem::offset_of!(RTCRay, u) - 64usize]; + ["Offset of field: RTCRay::v"][::std::mem::offset_of!(RTCRay, v) - 68usize]; + [ "Offset of field: RTCRay::geomID", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).primID) as usize - ptr as usize }, - 76usize, + ][::std::mem::offset_of!(RTCRay, geomID) - 72usize]; + [ "Offset of field: RTCRay::primID", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).instID) as usize - ptr as usize }, - 80usize, + ][::std::mem::offset_of!(RTCRay, primID) - 76usize]; + [ "Offset of field: RTCRay::instID", - ); -} + ][::std::mem::offset_of!(RTCRay, instID) - 80usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-1350-attribute-overloadable.rs b/bindgen-tests/tests/expectations/tests/issue-1350-attribute-overloadable.rs index 908ccfbc2e..c033570793 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1350-attribute-overloadable.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1350-attribute-overloadable.rs @@ -1,9 +1,9 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z11my_functioni"] pub fn my_function(a: ::std::os::raw::c_int); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z11my_functionPKc"] pub fn my_function1(a: *const ::std::os::raw::c_char); } diff --git a/bindgen-tests/tests/expectations/tests/issue-1375-prefixed-functions.rs b/bindgen-tests/tests/expectations/tests/issue-1375-prefixed-functions.rs index 2e9a594a31..f5e231ea96 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1375-prefixed-functions.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1375-prefixed-functions.rs @@ -1,13 +1,13 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}my_custom_prefix_var_const_name"] pub static var_const_name: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}my_custom_prefix_var_mut_name"] pub static mut var_mut_name: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}my_custom_prefix_function_name"] pub fn function_name(x: ::std::os::raw::c_int); } diff --git a/bindgen-tests/tests/expectations/tests/issue-1435.rs b/bindgen-tests/tests/expectations/tests/issue-1435.rs index 3040c1451e..b50e1f88c0 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1435.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1435.rs @@ -6,12 +6,12 @@ pub mod root { pub mod ns { #[allow(unused_imports)] use self::super::super::root; - pub const AB_A: root::ns::AB = 0; - pub const AB_B: root::ns::AB = 1; + pub const AB_A: AB = 0; + pub const AB_B: AB = 1; pub type AB = ::std::os::raw::c_int; } pub use self::super::root::ns::AB as AB; - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZL2kA"] pub static kA: root::AB; } diff --git a/bindgen-tests/tests/expectations/tests/issue-1488-enum-new-type.rs b/bindgen-tests/tests/expectations/tests/issue-1488-enum-new-type.rs index 60882da2d5..ab4b6fc971 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1488-enum-new-type.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1488-enum-new-type.rs @@ -6,6 +6,8 @@ pub type Foo = ::std::os::raw::c_uint; #[derive(Debug, Copy, Clone)] pub struct FooAlias(pub Foo); pub mod Bar { + #[allow(unused_imports)] + use super::*; pub type Type = ::std::os::raw::c_uint; pub const C: Type = 0; pub const D: Type = 1; diff --git a/bindgen-tests/tests/expectations/tests/issue-1947.rs b/bindgen-tests/tests/expectations/tests/issue-1947.rs index 32f9bbe146..795b033a12 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1947.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1947.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,17 +126,34 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } pub type U8 = ::std::os::raw::c_uchar; pub type U16 = ::std::os::raw::c_ushort; #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct V56AMDY { - pub _bitfield_align_1: [u16; 0], + pub _bindgen_align: [u16; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, pub MADK: U8, pub MABR: U8, - pub _bitfield_align_2: [u16; 0], pub _bitfield_2: __BindgenBitfieldUnit<[u8; 3usize]>, pub _rB_: U8, } @@ -117,6 +178,31 @@ impl V56AMDY { } } #[inline] + pub unsafe fn MADZ_raw(this: *const Self) -> U16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 10u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_MADZ_raw(this: *mut Self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 10u8, + val as u64, + ) + } + } + #[inline] pub fn MAI0(&self) -> U16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 2u8) as u16) } } @@ -128,6 +214,31 @@ impl V56AMDY { } } #[inline] + pub unsafe fn MAI0_raw(this: *const Self) -> U16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 10usize, 2u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_MAI0_raw(this: *mut Self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 10usize, + 2u8, + val as u64, + ) + } + } + #[inline] pub fn MAI1(&self) -> U16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 2u8) as u16) } } @@ -139,6 +250,31 @@ impl V56AMDY { } } #[inline] + pub unsafe fn MAI1_raw(this: *const Self) -> U16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 12usize, 2u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_MAI1_raw(this: *mut Self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 12usize, + 2u8, + val as u64, + ) + } + } + #[inline] pub fn MAI2(&self) -> U16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 2u8) as u16) } } @@ -150,6 +286,31 @@ impl V56AMDY { } } #[inline] + pub unsafe fn MAI2_raw(this: *const Self) -> U16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 14usize, 2u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_MAI2_raw(this: *mut Self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 14usize, + 2u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( MADZ: U16, MAI0: U16, @@ -207,6 +368,31 @@ impl V56AMDY { } } #[inline] + pub unsafe fn MATH_raw(this: *const Self) -> U16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 0usize, 10u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_MATH_raw(this: *mut Self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 0usize, + 10u8, + val as u64, + ) + } + } + #[inline] pub fn MATE(&self) -> U16 { unsafe { ::std::mem::transmute(self._bitfield_2.get(10usize, 4u8) as u16) } } @@ -218,6 +404,31 @@ impl V56AMDY { } } #[inline] + pub unsafe fn MATE_raw(this: *const Self) -> U16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 10usize, 4u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_MATE_raw(this: *mut Self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 10usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn MATW(&self) -> U16 { unsafe { ::std::mem::transmute(self._bitfield_2.get(14usize, 2u8) as u16) } } @@ -229,6 +440,31 @@ impl V56AMDY { } } #[inline] + pub unsafe fn MATW_raw(this: *const Self) -> U16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 14usize, 2u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_MATW_raw(this: *mut Self, val: U16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 14usize, + 2u8, + val as u64, + ) + } + } + #[inline] pub fn MASW(&self) -> U8 { unsafe { ::std::mem::transmute(self._bitfield_2.get(16usize, 4u8) as u8) } } @@ -240,6 +476,31 @@ impl V56AMDY { } } #[inline] + pub unsafe fn MASW_raw(this: *const Self) -> U8 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 16usize, 4u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_MASW_raw(this: *mut Self, val: U8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 16usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn MABW(&self) -> U8 { unsafe { ::std::mem::transmute(self._bitfield_2.get(20usize, 3u8) as u8) } } @@ -251,6 +512,31 @@ impl V56AMDY { } } #[inline] + pub unsafe fn MABW_raw(this: *const Self) -> U8 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 20usize, 3u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_MABW_raw(this: *mut Self, val: U8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 20usize, + 3u8, + val as u64, + ) + } + } + #[inline] pub fn MAXN(&self) -> U8 { unsafe { ::std::mem::transmute(self._bitfield_2.get(23usize, 1u8) as u8) } } @@ -262,6 +548,31 @@ impl V56AMDY { } } #[inline] + pub unsafe fn MAXN_raw(this: *const Self) -> U8 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 23usize, 1u8) + as u8, + ) + } + } + #[inline] + pub unsafe fn set_MAXN_raw(this: *mut Self, val: U8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 23usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_2( MATH: U16, MATE: U16, diff --git a/bindgen-tests/tests/expectations/tests/issue-2019.rs b/bindgen-tests/tests/expectations/tests/issue-2019.rs index 88921d615a..4c91cf9972 100644 --- a/bindgen-tests/tests/expectations/tests/issue-2019.rs +++ b/bindgen-tests/tests/expectations/tests/issue-2019.rs @@ -10,7 +10,7 @@ const _: () = { ["Alignment of A"][::std::mem::align_of::
() - 4usize]; ["Offset of field: A::a"][::std::mem::offset_of!(A, a) - 0usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1A4makeEv"] pub fn make() -> A; } @@ -31,7 +31,7 @@ const _: () = { ["Alignment of B"][::std::mem::align_of::() - 4usize]; ["Offset of field: B::b"][::std::mem::offset_of!(B, b) - 0usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1B4makeEv"] pub fn make1() -> B; } diff --git a/bindgen-tests/tests/expectations/tests/issue-2556.rs b/bindgen-tests/tests/expectations/tests/issue-2556.rs index 5f7c1d369a..92fe5026b8 100644 --- a/bindgen-tests/tests/expectations/tests/issue-2556.rs +++ b/bindgen-tests/tests/expectations/tests/issue-2556.rs @@ -23,7 +23,7 @@ pub mod root { pub mod foo { #[allow(unused_imports)] use self::super::super::root; - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN3fooL22kFallbackIntrinsicSizeE"] pub static kFallbackIntrinsicSize: root::nsSize; } diff --git a/bindgen-tests/tests/expectations/tests/issue-2618.rs b/bindgen-tests/tests/expectations/tests/issue-2618.rs new file mode 100644 index 0000000000..ecac1ec81e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-2618.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const val1: u32 = 2147483647; +pub const val2: u32 = 2147483648; +pub const val3: u32 = 4294967295; +pub const val4: u64 = 9223372036854775807; +pub const val5: u64 = 9223372036854775808; +pub const val6: u64 = 18446744073709551615; +pub const val7: u32 = 2147483647; +pub const val8: u32 = 2147483648; +pub const val9: u32 = 4294967295; +pub const val10: u64 = 9223372036854775807; +pub const val11: u64 = 9223372036854775808; +pub const val12: u64 = 18446744073709551615; diff --git a/bindgen-tests/tests/expectations/tests/issue-2966.rs b/bindgen-tests/tests/expectations/tests/issue-2966.rs new file mode 100644 index 0000000000..bfdcbd9e2f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-2966.rs @@ -0,0 +1,10 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct pub_var1(pub *const ::std::os::raw::c_char); +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct pubcrate_var2(pub(crate) *const ::std::os::raw::c_char); +#[repr(transparent)] +#[derive(Debug, Copy, Clone)] +pub struct private_var3(*const ::std::os::raw::c_char); diff --git a/bindgen-tests/tests/expectations/tests/issue-3027.rs b/bindgen-tests/tests/expectations/tests/issue-3027.rs new file mode 100644 index 0000000000..c8c2a7e542 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-3027.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub mod root { + #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] + #[repr(C)] + pub struct __BindgenOpaqueArray(pub T); + impl Default for __BindgenOpaqueArray<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } + } + #[allow(unused_imports)] + use self::super::root; + pub mod regression { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct C { + pub a: root::__BindgenOpaqueArray<[u8; 3usize]>, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of C"][::std::mem::size_of::() - 3usize]; + ["Alignment of C"][::std::mem::align_of::() - 1usize]; + ["Offset of field: C::a"][::std::mem::offset_of!(C, a) - 0usize]; + }; + } +} diff --git a/bindgen-tests/tests/expectations/tests/issue-372.rs b/bindgen-tests/tests/expectations/tests/issue-372.rs index 80b8cbe8b6..cf00a70743 100644 --- a/bindgen-tests/tests/expectations/tests/issue-372.rs +++ b/bindgen-tests/tests/expectations/tests/issue-372.rs @@ -1,6 +1,14 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] pub mod root { + #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] + #[repr(C, align(8))] + pub struct __BindgenOpaqueArray8(pub T); + impl Default for __BindgenOpaqueArray8<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } + } #[allow(unused_imports)] use self::super::root; #[repr(C)] @@ -10,28 +18,14 @@ pub mod root { pub k: *mut root::i, pub l: bool, } - #[test] - fn bindgen_test_layout_i() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 24usize, "Size of i"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of i"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).j) as usize - ptr as usize }, - 0usize, - "Offset of field: i::j", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).k) as usize - ptr as usize }, - 8usize, - "Offset of field: i::k", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).l) as usize - ptr as usize }, - 16usize, - "Offset of field: i::l", - ); - } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of i"][::std::mem::size_of::() - 24usize]; + ["Alignment of i"][::std::mem::align_of::() - 8usize]; + ["Offset of field: i::j"][::std::mem::offset_of!(i, j) - 0usize]; + ["Offset of field: i::k"][::std::mem::offset_of!(i, k) - 8usize]; + ["Offset of field: i::l"][::std::mem::offset_of!(i, l) - 16usize]; + }; impl Default for i { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -46,18 +40,12 @@ pub mod root { pub struct d { pub m: root::i, } - #[test] - fn bindgen_test_layout_d() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 24usize, "Size of d"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of d"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).m) as usize - ptr as usize }, - 0usize, - "Offset of field: d::m", - ); - } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of d"][::std::mem::size_of::() - 24usize]; + ["Alignment of d"][::std::mem::align_of::() - 8usize]; + ["Offset of field: d::m"][::std::mem::offset_of!(d, m) - 0usize]; + }; impl Default for d { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -84,28 +72,14 @@ pub mod root { ai = 11, } #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] pub struct F { - pub w: [u64; 33usize], - } - #[test] - fn bindgen_test_layout_F() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 264usize, "Size of F"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of F"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).w) as usize - ptr as usize }, - 0usize, - "Offset of field: F::w", - ); - } - impl Default for F { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } + pub w: root::__BindgenOpaqueArray8<[u8; 264usize]>, } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of F"][::std::mem::size_of::() - 264usize]; + ["Alignment of F"][::std::mem::align_of::() - 8usize]; + ["Offset of field: F::w"][::std::mem::offset_of!(F, w) - 0usize]; + }; } diff --git a/bindgen-tests/tests/expectations/tests/issue-410.rs b/bindgen-tests/tests/expectations/tests/issue-410.rs index e52aa25a13..cda9b6e338 100644 --- a/bindgen-tests/tests/expectations/tests/issue-410.rs +++ b/bindgen-tests/tests/expectations/tests/issue-410.rs @@ -16,7 +16,7 @@ pub mod root { ["Size of Value"][::std::mem::size_of::() - 1usize]; ["Alignment of Value"][::std::mem::align_of::() - 1usize]; }; - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN2JS5Value1aE10JSWhyMagic"] pub fn Value_a(this: *mut root::JS::Value, arg1: root::JSWhyMagic); } diff --git a/bindgen-tests/tests/expectations/tests/issue-447.rs b/bindgen-tests/tests/expectations/tests/issue-447.rs index 305fa739d0..8867a359a2 100644 --- a/bindgen-tests/tests/expectations/tests/issue-447.rs +++ b/bindgen-tests/tests/expectations/tests/issue-447.rs @@ -39,7 +39,7 @@ pub mod root { "Alignment of JSAutoCompartment", ][::std::mem::align_of::() - 1usize]; }; - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN17JSAutoCompartmentC1EN7mozilla6detail19GuardObjectNotifierE"] pub fn JSAutoCompartment_JSAutoCompartment( this: *mut root::JSAutoCompartment, diff --git a/bindgen-tests/tests/expectations/tests/issue-493_1_0.rs b/bindgen-tests/tests/expectations/tests/issue-493_1_0.rs deleted file mode 100644 index ff0c93428b..0000000000 --- a/bindgen-tests/tests/expectations/tests/issue-493_1_0.rs +++ /dev/null @@ -1,136 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct basic_string { - pub _address: u8, -} -pub type basic_string_size_type = ::std::os::raw::c_ulonglong; -pub type basic_string_value_type = ::std::os::raw::c_char; -pub type basic_string_pointer = *mut basic_string_value_type; -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct basic_string___long { - pub __cap_: basic_string_size_type, - pub __size_: basic_string_size_type, - pub __data_: basic_string_pointer, -} -impl Default for basic_string___long { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -pub const basic_string___min_cap: basic_string__bindgen_ty_1 = basic_string__bindgen_ty_1::__min_cap; -#[repr(i32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum basic_string__bindgen_ty_1 { - __min_cap = 0, -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct basic_string___short { - pub __bindgen_anon_1: basic_string___short__bindgen_ty_1, - pub __data_: *mut basic_string_value_type, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct basic_string___short__bindgen_ty_1 { - pub __size_: __BindgenUnionField<::std::os::raw::c_uchar>, - pub __lx: __BindgenUnionField, - pub bindgen_union_field: u8, -} -impl Default for basic_string___short { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct basic_string___ulx { - pub __lx: __BindgenUnionField, - pub __lxx: __BindgenUnionField, - pub bindgen_union_field: [u8; 0usize], -} -pub const basic_string___n_words: basic_string__bindgen_ty_2 = basic_string__bindgen_ty_2::__n_words; -#[repr(i32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum basic_string__bindgen_ty_2 { - __n_words = 0, -} -#[repr(C)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct basic_string___raw { - pub __words: *mut basic_string_size_type, -} -impl Default for basic_string___raw { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct basic_string___rep { - pub __bindgen_anon_1: basic_string___rep__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct basic_string___rep__bindgen_ty_1 { - pub __l: __BindgenUnionField, - pub __s: __BindgenUnionField, - pub __r: __BindgenUnionField, - pub bindgen_union_field: [u8; 0usize], -} diff --git a/bindgen-tests/tests/expectations/tests/issue-511.rs b/bindgen-tests/tests/expectations/tests/issue-511.rs index e2bb991946..9d26b334c3 100644 --- a/bindgen-tests/tests/expectations/tests/issue-511.rs +++ b/bindgen-tests/tests/expectations/tests/issue-511.rs @@ -1,13 +1,13 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub static mut a: *mut ::std::os::raw::c_char; } -extern "C" { +unsafe extern "C" { pub static mut b: *const ::std::os::raw::c_char; } -extern "C" { +unsafe extern "C" { pub static c: *mut ::std::os::raw::c_char; } -extern "C" { +unsafe extern "C" { pub static d: *const ::std::os::raw::c_char; } diff --git a/bindgen-tests/tests/expectations/tests/issue-537-repr-packed-n.rs b/bindgen-tests/tests/expectations/tests/issue-537-repr-packed-n.rs index 0142673f3e..881cb9c8ed 100644 --- a/bindgen-tests/tests/expectations/tests/issue-537-repr-packed-n.rs +++ b/bindgen-tests/tests/expectations/tests/issue-537-repr-packed-n.rs @@ -7,44 +7,28 @@ pub struct AlignedToOne { pub i: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_AlignedToOne() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of AlignedToOne"); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - "Alignment of AlignedToOne", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).i) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AlignedToOne"][::std::mem::size_of::() - 4usize]; + ["Alignment of AlignedToOne"][::std::mem::align_of::() - 1usize]; + [ "Offset of field: AlignedToOne::i", - ); -} + ][::std::mem::offset_of!(AlignedToOne, i) - 0usize]; +}; /// This should be packed because Rust 1.33 has `#[repr(packed(N))]`. #[repr(C, packed(2))] #[derive(Debug, Default, Copy, Clone)] pub struct AlignedToTwo { pub i: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_AlignedToTwo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of AlignedToTwo"); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of AlignedToTwo", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).i) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AlignedToTwo"][::std::mem::size_of::() - 4usize]; + ["Alignment of AlignedToTwo"][::std::mem::align_of::() - 2usize]; + [ "Offset of field: AlignedToTwo::i", - ); -} + ][::std::mem::offset_of!(AlignedToTwo, i) - 0usize]; +}; /** This should not be opaque because although `libclang` doesn't give us the `#pragma pack(1)`, we can detect that alignment is 1 and add `#[repr(packed)]` to the struct ourselves.*/ @@ -54,27 +38,13 @@ pub struct PackedToOne { pub x: ::std::os::raw::c_int, pub y: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_PackedToOne() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of PackedToOne"); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - "Alignment of PackedToOne", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, - 0usize, - "Offset of field: PackedToOne::x", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, - 4usize, - "Offset of field: PackedToOne::y", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of PackedToOne"][::std::mem::size_of::() - 8usize]; + ["Alignment of PackedToOne"][::std::mem::align_of::() - 1usize]; + ["Offset of field: PackedToOne::x"][::std::mem::offset_of!(PackedToOne, x) - 0usize]; + ["Offset of field: PackedToOne::y"][::std::mem::offset_of!(PackedToOne, y) - 4usize]; +}; /// This should be packed because Rust 1.33 has `#[repr(packed(N))]`. #[repr(C, packed(2))] #[derive(Debug, Default, Copy, Clone)] @@ -82,24 +52,10 @@ pub struct PackedToTwo { pub x: ::std::os::raw::c_int, pub y: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_PackedToTwo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of PackedToTwo"); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of PackedToTwo", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, - 0usize, - "Offset of field: PackedToTwo::x", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, - 4usize, - "Offset of field: PackedToTwo::y", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of PackedToTwo"][::std::mem::size_of::() - 8usize]; + ["Alignment of PackedToTwo"][::std::mem::align_of::() - 2usize]; + ["Offset of field: PackedToTwo::x"][::std::mem::offset_of!(PackedToTwo, x) - 0usize]; + ["Offset of field: PackedToTwo::y"][::std::mem::offset_of!(PackedToTwo, y) - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/issue-544-stylo-creduce-2.rs b/bindgen-tests/tests/expectations/tests/issue-544-stylo-creduce-2.rs index c81b672956..a160d0275d 100644 --- a/bindgen-tests/tests/expectations/tests/issue-544-stylo-creduce-2.rs +++ b/bindgen-tests/tests/expectations/tests/issue-544-stylo-creduce-2.rs @@ -1,10 +1,18 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C)] +pub struct __BindgenOpaqueArray(pub T); +impl Default for __BindgenOpaqueArray<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Foo { pub member: *mut Foo_SecondAlias, } -pub type Foo_FirstAlias = [u8; 0usize]; +pub type Foo_FirstAlias = __BindgenOpaqueArray<[u8; 0usize]>; pub type Foo_SecondAlias = Foo; impl Default for Foo { fn default() -> Self { diff --git a/bindgen-tests/tests/expectations/tests/issue-574-assertion-failure-in-codegen.rs b/bindgen-tests/tests/expectations/tests/issue-574-assertion-failure-in-codegen.rs index 85f66c5a73..9968501397 100644 --- a/bindgen-tests/tests/expectations/tests/issue-574-assertion-failure-in-codegen.rs +++ b/bindgen-tests/tests/expectations/tests/issue-574-assertion-failure-in-codegen.rs @@ -17,7 +17,7 @@ const _: () = { "Offset of field: _bindgen_ty_1::ar", ][::std::mem::offset_of!(_bindgen_ty_1, ar) - 0usize]; }; -extern "C" { +unsafe extern "C" { pub static mut AutoIdVector: _bindgen_ty_1; } #[allow(clippy::unnecessary_operation, clippy::identity_op)] diff --git a/bindgen-tests/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs b/bindgen-tests/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs index e53b10d4af..2a85837e3d 100644 --- a/bindgen-tests/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs +++ b/bindgen-tests/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs @@ -67,7 +67,7 @@ impl Default for b { } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z25Servo_Element_GetSnapshotv"] pub fn Servo_Element_GetSnapshot() -> A; } diff --git a/bindgen-tests/tests/expectations/tests/issue-648-derive-debug-with-padding.rs b/bindgen-tests/tests/expectations/tests/issue-648-derive-debug-with-padding.rs index 08e47bc2c6..5d87159f97 100644 --- a/bindgen-tests/tests/expectations/tests/issue-648-derive-debug-with-padding.rs +++ b/bindgen-tests/tests/expectations/tests/issue-648-derive-debug-with-padding.rs @@ -3,22 +3,16 @@ Debug/Hash because 63 is over the hard coded limit.*/ #[repr(C)] #[repr(align(64))] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct NoDebug { pub c: ::std::os::raw::c_char, } -#[test] -fn bindgen_test_layout_NoDebug() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 64usize, "Size of NoDebug"); - assert_eq!(::std::mem::align_of::(), 64usize, "Alignment of NoDebug"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).c) as usize - ptr as usize }, - 0usize, - "Offset of field: NoDebug::c", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of NoDebug"][::std::mem::size_of::() - 64usize]; + ["Alignment of NoDebug"][::std::mem::align_of::() - 64usize]; + ["Offset of field: NoDebug::c"][::std::mem::offset_of!(NoDebug, c) - 0usize]; +}; impl Default for NoDebug { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -28,47 +22,32 @@ impl Default for NoDebug { } } } -impl ::std::cmp::PartialEq for NoDebug { - fn eq(&self, other: &NoDebug) -> bool { - self.c == other.c - } -} /** This should derive Debug/Hash/PartialEq/Eq because the padding size is less than the max derive Debug/Hash/PartialEq/Eq impl for arrays. However, we conservatively don't derive Debug/Hash because we determine Debug derive-ability before we compute padding, which happens at codegen.*/ #[repr(C)] #[repr(align(64))] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct ShouldDeriveDebugButDoesNot { pub c: [::std::os::raw::c_char; 32usize], pub d: ::std::os::raw::c_char, } -#[test] -fn bindgen_test_layout_ShouldDeriveDebugButDoesNot() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 64usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of ShouldDeriveDebugButDoesNot", - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, + ][::std::mem::size_of::() - 64usize]; + [ "Alignment of ShouldDeriveDebugButDoesNot", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).c) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 64usize]; + [ "Offset of field: ShouldDeriveDebugButDoesNot::c", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).d) as usize - ptr as usize }, - 32usize, + ][::std::mem::offset_of!(ShouldDeriveDebugButDoesNot, c) - 0usize]; + [ "Offset of field: ShouldDeriveDebugButDoesNot::d", - ); -} + ][::std::mem::offset_of!(ShouldDeriveDebugButDoesNot, d) - 32usize]; +}; impl Default for ShouldDeriveDebugButDoesNot { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -78,8 +57,3 @@ impl Default for ShouldDeriveDebugButDoesNot { } } } -impl ::std::cmp::PartialEq for ShouldDeriveDebugButDoesNot { - fn eq(&self, other: &ShouldDeriveDebugButDoesNot) -> bool { - self.c == other.c && self.d == other.d - } -} diff --git a/bindgen-tests/tests/expectations/tests/issue-654-struct-fn-collision.rs b/bindgen-tests/tests/expectations/tests/issue-654-struct-fn-collision.rs index 289dac9a1c..6bf02be74e 100644 --- a/bindgen-tests/tests/expectations/tests/issue-654-struct-fn-collision.rs +++ b/bindgen-tests/tests/expectations/tests/issue-654-struct-fn-collision.rs @@ -4,6 +4,6 @@ pub struct foo { _unused: [u8; 0], } -extern "C" { +unsafe extern "C" { pub fn foo() -> ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs b/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs index 84dc763e6f..bc1951e7d1 100644 --- a/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs @@ -16,10 +16,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -29,21 +26,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -66,6 +90,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -83,11 +127,29 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Foo { - pub _bitfield_align_1: [u64; 0], + pub _bindgen_align: [u64; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 32usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -108,6 +170,31 @@ impl Foo { } } #[inline] + pub unsafe fn m_bitfield_raw(this: *const Self) -> ::std::os::raw::c_ulong { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 32usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 64u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_m_bitfield_raw(this: *mut Self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 32usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 64u8, + val as u64, + ) + } + } + #[inline] pub fn m_bar(&self) -> ::std::os::raw::c_ulong { unsafe { ::std::mem::transmute(self._bitfield_1.get(64usize, 64u8) as u64) } } @@ -119,6 +206,31 @@ impl Foo { } } #[inline] + pub unsafe fn m_bar_raw(this: *const Self) -> ::std::os::raw::c_ulong { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 32usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 64usize, 64u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_m_bar_raw(this: *mut Self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 32usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 64usize, + 64u8, + val as u64, + ) + } + } + #[inline] pub fn foo(&self) -> ::std::os::raw::c_ulong { unsafe { ::std::mem::transmute(self._bitfield_1.get(128usize, 1u8) as u64) } } @@ -130,6 +242,31 @@ impl Foo { } } #[inline] + pub unsafe fn foo_raw(this: *const Self) -> ::std::os::raw::c_ulong { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 32usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 128usize, 1u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_foo_raw(this: *mut Self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 32usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 128usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bar(&self) -> ::std::os::raw::c_ulong { unsafe { ::std::mem::transmute(self._bitfield_1.get(192usize, 64u8) as u64) } } @@ -141,6 +278,31 @@ impl Foo { } } #[inline] + pub unsafe fn bar_raw(this: *const Self) -> ::std::os::raw::c_ulong { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 32usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 192usize, 64u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_bar_raw(this: *mut Self, val: ::std::os::raw::c_ulong) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 32usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 192usize, + 64u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( m_bitfield: ::std::os::raw::c_ulong, m_bar: ::std::os::raw::c_ulong, diff --git a/bindgen-tests/tests/expectations/tests/issue-743.rs b/bindgen-tests/tests/expectations/tests/issue-743.rs new file mode 100644 index 0000000000..af3eb5bf6e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-743.rs @@ -0,0 +1,225 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit { + storage: Storage, +} +impl __BindgenBitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage } + } +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + fn extract_bit(byte: u8, index: usize) -> bool { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct S { + pub p: *mut ::std::os::raw::c_void, + pub b: bool, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, + pub __bindgen_padding_0: [u8; 5usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of S"][::std::mem::size_of::() - 16usize]; + ["Alignment of S"][::std::mem::align_of::() - 8usize]; + ["Offset of field: S::p"][::std::mem::offset_of!(S, p) - 0usize]; + ["Offset of field: S::b"][::std::mem::offset_of!(S, b) - 8usize]; +}; +impl Default for S { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl S { + #[inline] + pub fn u(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 16u8) as u32) } + } + #[inline] + pub fn set_u(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 16u8, val as u64) + } + } + #[inline] + pub unsafe fn u_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 16u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_u_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 16u8, + val as u64, + ) + } + } + #[inline] + pub fn new_bitfield_1( + u: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 16u8, + { + let u: u32 = unsafe { ::std::mem::transmute(u) }; + u as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/issue-801-opaque-sloppiness.rs b/bindgen-tests/tests/expectations/tests/issue-801-opaque-sloppiness.rs index b08ef2fd1d..90eb048640 100644 --- a/bindgen-tests/tests/expectations/tests/issue-801-opaque-sloppiness.rs +++ b/bindgen-tests/tests/expectations/tests/issue-801-opaque-sloppiness.rs @@ -15,7 +15,7 @@ const _: () = { ["Size of B"][::std::mem::size_of::() - 1usize]; ["Alignment of B"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1B1aE"] pub static mut B_a: A; } diff --git a/bindgen-tests/tests/expectations/tests/issue-807-opaque-types-methods-being-generated.rs b/bindgen-tests/tests/expectations/tests/issue-807-opaque-types-methods-being-generated.rs index c0150a73f0..3d3ee5e590 100644 --- a/bindgen-tests/tests/expectations/tests/issue-807-opaque-types-methods-being-generated.rs +++ b/bindgen-tests/tests/expectations/tests/issue-807-opaque-types-methods-being-generated.rs @@ -40,11 +40,11 @@ const _: () = { ["Size of Opaque"][::std::mem::size_of::() - 1usize]; ["Alignment of Opaque"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN6Opaque17eleven_out_of_tenEv"] pub fn Opaque_eleven_out_of_ten(this: *mut Opaque) -> SuchWow; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN6OpaqueC1E6Pupper"] pub fn Opaque_Opaque(this: *mut Opaque, pup: Pupper); } @@ -60,7 +60,7 @@ impl Opaque { __bindgen_tmp.assume_init() } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN6Opaque11MAJESTIC_AFE"] pub static mut Opaque_MAJESTIC_AF: Doggo; } diff --git a/bindgen-tests/tests/expectations/tests/issue-816.rs b/bindgen-tests/tests/expectations/tests/issue-816.rs index 1f1112eff5..b1494afede 100644 --- a/bindgen-tests/tests/expectations/tests/issue-816.rs +++ b/bindgen-tests/tests/expectations/tests/issue-816.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,12 +126,29 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] -#[repr(align(4))] #[derive(Debug, Default, Copy, Clone)] pub struct capabilities { - pub _bitfield_align_1: [u8; 0], + pub _bindgen_align: [u32; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 16usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -108,6 +169,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_1_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_1_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_2(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u32) } } @@ -119,6 +205,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_2_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_2_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_3(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u32) } } @@ -130,6 +241,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_3_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_3_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 2usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_4(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u32) } } @@ -141,6 +277,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_4_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 3usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_4_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 3usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_5(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u32) } } @@ -152,6 +313,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_5_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_5_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 4usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_6(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u32) } } @@ -163,6 +349,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_6_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 5usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_6_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 5usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_7(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u32) } } @@ -174,6 +385,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_7_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 6usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_7_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 6usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_8(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u32) } } @@ -185,6 +421,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_8_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 7usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_8_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 7usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_9(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u32) } } @@ -196,6 +457,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_9_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 8usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_9_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 8usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_10(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 1u8) as u32) } } @@ -207,6 +493,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_10_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 9usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_10_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 9usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_11(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(10usize, 1u8) as u32) } } @@ -218,6 +529,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_11_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 10usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_11_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 10usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_12(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 1u8) as u32) } } @@ -229,6 +565,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_12_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 11usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_12_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 11usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_13(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 1u8) as u32) } } @@ -240,6 +601,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_13_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 12usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_13_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 12usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_14(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(13usize, 1u8) as u32) } } @@ -251,6 +637,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_14_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 13usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_14_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 13usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_15(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 1u8) as u32) } } @@ -262,6 +673,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_15_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 14usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_15_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 14usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_16(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(15usize, 1u8) as u32) } } @@ -273,6 +709,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_16_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 15usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_16_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 15usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_17(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 1u8) as u32) } } @@ -284,6 +745,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_17_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 16usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_17_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 16usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_18(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(17usize, 1u8) as u32) } } @@ -295,6 +781,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_18_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 17usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_18_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 17usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_19(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(18usize, 1u8) as u32) } } @@ -306,6 +817,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_19_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 18usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_19_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 18usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_20(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(19usize, 1u8) as u32) } } @@ -317,6 +853,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_20_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 19usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_20_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 19usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_21(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(20usize, 1u8) as u32) } } @@ -328,6 +889,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_21_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 20usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_21_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 20usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_22(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(21usize, 1u8) as u32) } } @@ -339,6 +925,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_22_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 21usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_22_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 21usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_23(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(22usize, 1u8) as u32) } } @@ -350,6 +961,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_23_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 22usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_23_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 22usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_24(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(23usize, 1u8) as u32) } } @@ -361,6 +997,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_24_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 23usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_24_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 23usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_25(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 1u8) as u32) } } @@ -372,6 +1033,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_25_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 24usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_25_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 24usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_26(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(25usize, 1u8) as u32) } } @@ -383,6 +1069,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_26_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 25usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_26_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 25usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_27(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(26usize, 1u8) as u32) } } @@ -394,6 +1105,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_27_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 26usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_27_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 26usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_28(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(27usize, 1u8) as u32) } } @@ -405,6 +1141,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_28_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 27usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_28_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 27usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_29(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(28usize, 1u8) as u32) } } @@ -416,6 +1177,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_29_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 28usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_29_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 28usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_30(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(29usize, 1u8) as u32) } } @@ -427,6 +1213,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_30_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 29usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_30_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 29usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_31(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(30usize, 1u8) as u32) } } @@ -438,6 +1249,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_31_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 30usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_31_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 30usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_32(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(31usize, 1u8) as u32) } } @@ -449,6 +1285,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_32_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 31usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_32_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 31usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_33(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(32usize, 1u8) as u32) } } @@ -460,6 +1321,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_33_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 32usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_33_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 32usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_34(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(33usize, 1u8) as u32) } } @@ -471,6 +1357,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_34_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 33usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_34_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 33usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_35(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(34usize, 1u8) as u32) } } @@ -482,6 +1393,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_35_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 34usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_35_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 34usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_36(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(35usize, 1u8) as u32) } } @@ -493,6 +1429,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_36_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 35usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_36_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 35usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_37(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(36usize, 1u8) as u32) } } @@ -504,6 +1465,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_37_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 36usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_37_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 36usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_38(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(37usize, 1u8) as u32) } } @@ -515,6 +1501,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_38_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 37usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_38_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 37usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_39(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(38usize, 1u8) as u32) } } @@ -526,6 +1537,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_39_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 38usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_39_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 38usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_40(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(39usize, 1u8) as u32) } } @@ -537,6 +1573,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_40_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 39usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_40_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 39usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn bit_41(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(40usize, 1u8) as u32) } } @@ -548,6 +1609,31 @@ impl capabilities { } } #[inline] + pub unsafe fn bit_41_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 40usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bit_41_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 16usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 40usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( bit_1: ::std::os::raw::c_uint, bit_2: ::std::os::raw::c_uint, diff --git a/bindgen-tests/tests/expectations/tests/issue-833-1.rs b/bindgen-tests/tests/expectations/tests/issue-833-1.rs index b86a4e0df3..5aa8c3078b 100644 --- a/bindgen-tests/tests/expectations/tests/issue-833-1.rs +++ b/bindgen-tests/tests/expectations/tests/issue-833-1.rs @@ -3,6 +3,6 @@ pub struct nsTArray { pub hdr: *const (), } -extern "C" { +unsafe extern "C" { pub fn func() -> *mut nsTArray; } diff --git a/bindgen-tests/tests/expectations/tests/issue-833.rs b/bindgen-tests/tests/expectations/tests/issue-833.rs index 2a2d375e89..9698fdb479 100644 --- a/bindgen-tests/tests/expectations/tests/issue-833.rs +++ b/bindgen-tests/tests/expectations/tests/issue-833.rs @@ -3,6 +3,6 @@ pub struct nsTArray { pub hdr: *const T, } -extern "C" { +unsafe extern "C" { pub fn func() -> *mut nsTArray<::std::os::raw::c_int>; } diff --git a/bindgen-tests/tests/expectations/tests/issue-848-replacement-system-include.rs b/bindgen-tests/tests/expectations/tests/issue-848-replacement-system-include.rs index d224612ba9..6beeae69d8 100644 --- a/bindgen-tests/tests/expectations/tests/issue-848-replacement-system-include.rs +++ b/bindgen-tests/tests/expectations/tests/issue-848-replacement-system-include.rs @@ -20,6 +20,6 @@ impl Default for nsTArray { } } } -extern "C" { +unsafe extern "C" { pub fn func() -> *mut nsTArray<::std::os::raw::c_int>; } diff --git a/bindgen-tests/tests/expectations/tests/issue-888-enum-var-decl-jump.rs b/bindgen-tests/tests/expectations/tests/issue-888-enum-var-decl-jump.rs index 0a0d05f9f9..023c8695e3 100644 --- a/bindgen-tests/tests/expectations/tests/issue-888-enum-var-decl-jump.rs +++ b/bindgen-tests/tests/expectations/tests/issue-888-enum-var-decl-jump.rs @@ -11,7 +11,7 @@ pub mod root { pub struct Type { pub _address: u8, } - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN6Halide4Type1bE"] pub static mut Type_b: root::a; } diff --git a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs index e7cb9af39e..dc0ef8ed7f 100644 --- a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs +++ b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,6 +126,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } pub const JSVAL_TAG_SHIFT: u32 = 47; pub const JSVAL_PAYLOAD_MASK: u64 = 140737488355327; @@ -183,7 +245,7 @@ pub union jsval_layout { #[repr(C)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct jsval_layout__bindgen_ty_1 { - pub _bitfield_align_1: [u64; 0], + pub _bindgen_align: [u64; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -217,6 +279,31 @@ impl jsval_layout__bindgen_ty_1 { } } #[inline] + pub unsafe fn payload47_raw(this: *const Self) -> u64 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 47u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_payload47_raw(this: *mut Self, val: u64) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 47u8, + val as u64, + ) + } + } + #[inline] pub fn tag(&self) -> JSValueTag { unsafe { ::std::mem::transmute(self._bitfield_1.get(47usize, 17u8) as u32) } } @@ -228,6 +315,31 @@ impl jsval_layout__bindgen_ty_1 { } } #[inline] + pub unsafe fn tag_raw(this: *const Self) -> JSValueTag { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 47usize, 17u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_tag_raw(this: *mut Self, val: JSValueTag) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 47usize, + 17u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( payload47: u64, tag: JSValueTag, diff --git a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs deleted file mode 100644 index 7ae53bc40f..0000000000 --- a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs +++ /dev/null @@ -1,455 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct __BindgenBitfieldUnit { - storage: Storage, -} -impl __BindgenBitfieldUnit { - #[inline] - pub fn new(storage: Storage) -> Self { - Self { storage } - } -} -impl __BindgenBitfieldUnit -where - Storage: AsRef<[u8]> + AsMut<[u8]>, -{ - #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; - let bit_index = if cfg!(target_endian = "big") { - 7 - (index % 8) - } else { - index % 8 - }; - let mask = 1 << bit_index; - byte & mask == mask - } - #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; - let bit_index = if cfg!(target_endian = "big") { - 7 - (index % 8) - } else { - index % 8 - }; - let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } - } - #[inline] - pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { - debug_assert!(bit_width <= 64); - debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); - debug_assert!( - (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), - ); - let mut val = 0; - for i in 0..(bit_width as usize) { - if self.get_bit(i + bit_offset) { - let index = if cfg!(target_endian = "big") { - bit_width as usize - 1 - i - } else { - i - }; - val |= 1 << index; - } - } - val - } - #[inline] - pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { - debug_assert!(bit_width <= 64); - debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); - debug_assert!( - (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), - ); - for i in 0..(bit_width as usize) { - let mask = 1 << i; - let val_bit_is_set = val & mask == mask; - let index = if cfg!(target_endian = "big") { - bit_width as usize - 1 - i - } else { - i - }; - self.set_bit(index + bit_offset, val_bit_is_set); - } - } -} -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -pub const JSVAL_TAG_SHIFT: u32 = 47; -pub const JSVAL_PAYLOAD_MASK: u64 = 140737488355327; -pub const JSVAL_TAG_MASK: i64 = -140737488355328; -#[repr(u8)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum JSValueType { - JSVAL_TYPE_DOUBLE = 0, - JSVAL_TYPE_INT32 = 1, - JSVAL_TYPE_UNDEFINED = 2, - JSVAL_TYPE_BOOLEAN = 3, - JSVAL_TYPE_MAGIC = 4, - JSVAL_TYPE_STRING = 5, - JSVAL_TYPE_SYMBOL = 6, - JSVAL_TYPE_NULL = 7, - JSVAL_TYPE_OBJECT = 8, - JSVAL_TYPE_UNKNOWN = 32, - JSVAL_TYPE_MISSING = 33, -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum JSValueTag { - JSVAL_TAG_MAX_DOUBLE = 131056, - JSVAL_TAG_INT32 = 131057, - JSVAL_TAG_UNDEFINED = 131058, - JSVAL_TAG_STRING = 131061, - JSVAL_TAG_SYMBOL = 131062, - JSVAL_TAG_BOOLEAN = 131059, - JSVAL_TAG_MAGIC = 131060, - JSVAL_TAG_NULL = 131063, - JSVAL_TAG_OBJECT = 131064, -} -#[repr(u64)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum JSValueShiftedTag { - JSVAL_SHIFTED_TAG_MAX_DOUBLE = 18444492278190833663, - JSVAL_SHIFTED_TAG_INT32 = 18444633011384221696, - JSVAL_SHIFTED_TAG_UNDEFINED = 18444773748872577024, - JSVAL_SHIFTED_TAG_STRING = 18445195961337643008, - JSVAL_SHIFTED_TAG_SYMBOL = 18445336698825998336, - JSVAL_SHIFTED_TAG_BOOLEAN = 18444914486360932352, - JSVAL_SHIFTED_TAG_MAGIC = 18445055223849287680, - JSVAL_SHIFTED_TAG_NULL = 18445477436314353664, - JSVAL_SHIFTED_TAG_OBJECT = 18445618173802708992, -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum JSWhyMagic { - /// a hole in a native object's elements - JS_ELEMENTS_HOLE = 0, - /// there is not a pending iterator value - JS_NO_ITER_VALUE = 1, - /// exception value thrown when closing a generator - JS_GENERATOR_CLOSING = 2, - /// compiler sentinel value - JS_NO_CONSTANT = 3, - /// used in debug builds to catch tracing errors - JS_THIS_POISON = 4, - /// used in debug builds to catch tracing errors - JS_ARG_POISON = 5, - /// an empty subnode in the AST serializer - JS_SERIALIZE_NO_NODE = 6, - /// lazy arguments value on the stack - JS_LAZY_ARGUMENTS = 7, - /// optimized-away 'arguments' value - JS_OPTIMIZED_ARGUMENTS = 8, - /// magic value passed to natives to indicate construction - JS_IS_CONSTRUCTING = 9, - /// arguments.callee has been overwritten - JS_OVERWRITTEN_CALLEE = 10, - /// value of static block object slot - JS_BLOCK_NEEDS_CLONE = 11, - /// see class js::HashableValue - JS_HASH_KEY_EMPTY = 12, - /// error while running Ion code - JS_ION_ERROR = 13, - /// missing recover instruction result - JS_ION_BAILOUT = 14, - /// optimized out slot - JS_OPTIMIZED_OUT = 15, - /// uninitialized lexical bindings that produce ReferenceError on touch. - JS_UNINITIALIZED_LEXICAL = 16, - /// for local use - JS_GENERIC_MAGIC = 17, - /// for local use - JS_WHY_MAGIC_COUNT = 18, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq)] -pub struct jsval_layout { - pub asBits: __BindgenUnionField, - pub debugView: __BindgenUnionField, - pub s: __BindgenUnionField, - pub asDouble: __BindgenUnionField, - pub asPtr: __BindgenUnionField<*mut ::std::os::raw::c_void>, - pub asWord: __BindgenUnionField, - pub asUIntPtr: __BindgenUnionField, - pub bindgen_union_field: u64, -} -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct jsval_layout__bindgen_ty_1 { - pub _bitfield_align_1: [u64; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, -} -#[test] -fn bindgen_test_layout_jsval_layout__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of jsval_layout__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of jsval_layout__bindgen_ty_1", - ); -} -impl Clone for jsval_layout__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -impl Default for jsval_layout__bindgen_ty_1 { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -impl jsval_layout__bindgen_ty_1 { - #[inline] - pub fn payload47(&self) -> u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 47u8) as u64) } - } - #[inline] - pub fn set_payload47(&mut self, val: u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 47u8, val as u64) - } - } - #[inline] - pub fn tag(&self) -> JSValueTag { - unsafe { ::std::mem::transmute(self._bitfield_1.get(47usize, 17u8) as u32) } - } - #[inline] - pub fn set_tag(&mut self, val: JSValueTag) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(47usize, 17u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - payload47: u64, - tag: JSValueTag, - ) -> __BindgenBitfieldUnit<[u8; 8usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default(); - __bindgen_bitfield_unit - .set( - 0usize, - 47u8, - { - let payload47: u64 = unsafe { ::std::mem::transmute(payload47) }; - payload47 as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 47usize, - 17u8, - { - let tag: u32 = unsafe { ::std::mem::transmute(tag) }; - tag as u64 - }, - ); - __bindgen_bitfield_unit - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct jsval_layout__bindgen_ty_2 { - pub payload: jsval_layout__bindgen_ty_2__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct jsval_layout__bindgen_ty_2__bindgen_ty_1 { - pub i32_: __BindgenUnionField, - pub u32_: __BindgenUnionField, - pub why: __BindgenUnionField, - pub bindgen_union_field: u32, -} -#[test] -fn bindgen_test_layout_jsval_layout__bindgen_ty_2__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of jsval_layout__bindgen_ty_2__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of jsval_layout__bindgen_ty_2__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).i32_) as usize - ptr as usize }, - 0usize, - "Offset of field: jsval_layout__bindgen_ty_2__bindgen_ty_1::i32_", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).u32_) as usize - ptr as usize }, - 0usize, - "Offset of field: jsval_layout__bindgen_ty_2__bindgen_ty_1::u32_", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).why) as usize - ptr as usize }, - 0usize, - "Offset of field: jsval_layout__bindgen_ty_2__bindgen_ty_1::why", - ); -} -impl Clone for jsval_layout__bindgen_ty_2__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_jsval_layout__bindgen_ty_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of jsval_layout__bindgen_ty_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of jsval_layout__bindgen_ty_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).payload) as usize - ptr as usize }, - 0usize, - "Offset of field: jsval_layout__bindgen_ty_2::payload", - ); -} -impl Clone for jsval_layout__bindgen_ty_2 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_jsval_layout() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of jsval_layout"); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of jsval_layout", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).asBits) as usize - ptr as usize }, - 0usize, - "Offset of field: jsval_layout::asBits", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).debugView) as usize - ptr as usize }, - 0usize, - "Offset of field: jsval_layout::debugView", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).s) as usize - ptr as usize }, - 0usize, - "Offset of field: jsval_layout::s", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).asDouble) as usize - ptr as usize }, - 0usize, - "Offset of field: jsval_layout::asDouble", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).asPtr) as usize - ptr as usize }, - 0usize, - "Offset of field: jsval_layout::asPtr", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).asWord) as usize - ptr as usize }, - 0usize, - "Offset of field: jsval_layout::asWord", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).asUIntPtr) as usize - ptr as usize }, - 0usize, - "Offset of field: jsval_layout::asUIntPtr", - ); -} -impl Clone for jsval_layout { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq)] -pub struct Value { - pub data: jsval_layout, -} -#[test] -fn bindgen_test_layout_Value() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of Value"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of Value"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).data) as usize - ptr as usize }, - 0usize, - "Offset of field: Value::data", - ); -} -impl Clone for Value { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/keywords.rs b/bindgen-tests/tests/expectations/tests/keywords.rs index d07f241376..0a55ee0463 100644 --- a/bindgen-tests/tests/expectations/tests/keywords.rs +++ b/bindgen-tests/tests/expectations/tests/keywords.rs @@ -1,221 +1,225 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}u8"] pub static mut u8_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}u16"] pub static mut u16_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}u32"] pub static mut u32_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}u64"] pub static mut u64_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}i8"] pub static mut i8_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}i16"] pub static mut i16_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}i32"] pub static mut i32_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}i64"] pub static mut i64_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}f32"] pub static mut f32_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}f64"] pub static mut f64_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}usize"] pub static mut usize_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}isize"] pub static mut isize_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}bool"] pub static mut bool_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}str"] pub static mut str_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}dyn"] pub static mut dyn_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}as"] pub static mut as_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}async"] pub static mut async_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}await"] pub static mut await_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}box"] pub static mut box_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}crate"] pub static mut crate_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}false"] pub static mut false_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}fn"] pub static mut fn_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { + #[link_name = "\u{1}gen"] + pub static mut gen_: ::std::os::raw::c_int; +} +unsafe extern "C" { #[link_name = "\u{1}impl"] pub static mut impl_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}in"] pub static mut in_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}let"] pub static mut let_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}loop"] pub static mut loop_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}match"] pub static mut match_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}mod"] pub static mut mod_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}move"] pub static mut move_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}mut"] pub static mut mut_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}pub"] pub static mut pub_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}ref"] pub static mut ref_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}self"] pub static mut self_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}Self"] pub static mut Self_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}super"] pub static mut super_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}trait"] pub static mut trait_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}true"] pub static mut true_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}try"] pub static mut try_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}type"] pub static mut type_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}unsafe"] pub static mut unsafe_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}use"] pub static mut use_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}where"] pub static mut where_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}abstract"] pub static mut abstract_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}alignof"] pub static mut alignof_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}become"] pub static mut become_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}final"] pub static mut final_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}macro"] pub static mut macro_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}offsetof"] pub static mut offsetof_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}override"] pub static mut override_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}priv"] pub static mut priv_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}proc"] pub static mut proc_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}pure"] pub static mut pure_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}unsized"] pub static mut unsized_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}virtual"] pub static mut virtual_: ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}yield"] pub static mut yield_: ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/layout.rs b/bindgen-tests/tests/expectations/tests/layout.rs index 8c4819f543..fe64295a68 100644 --- a/bindgen-tests/tests/expectations/tests/layout.rs +++ b/bindgen-tests/tests/expectations/tests/layout.rs @@ -1,18 +1 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct header { - pub _bindgen_opaque_blob: [u8; 16usize], -} -#[test] -fn bindgen_test_layout_header() { - assert_eq!(::std::mem::size_of::
(), 16usize, "Size of header"); -} -impl Default for header { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] \ No newline at end of file diff --git a/bindgen-tests/tests/expectations/tests/layout_align.rs b/bindgen-tests/tests/expectations/tests/layout_align.rs index c641ff843f..a942adb8f2 100644 --- a/bindgen-tests/tests/expectations/tests/layout_align.rs +++ b/bindgen-tests/tests/expectations/tests/layout_align.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,6 +126,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Default)] @@ -157,12 +219,11 @@ impl Default for rte_kni_fifo { } } #[repr(C)] -#[repr(align(8))] #[derive(Debug, Default, Copy, Clone)] pub struct rte_eth_link { + pub _bindgen_align: [u64; 0], ///< ETH_SPEED_NUM_ pub link_speed: u32, - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub __bindgen_padding_0: [u8; 3usize], } @@ -187,6 +248,31 @@ impl rte_eth_link { } } #[inline] + pub unsafe fn link_duplex_raw(this: *const Self) -> u16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_link_duplex_raw(this: *mut Self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn link_autoneg(&self) -> u16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) } } @@ -198,6 +284,31 @@ impl rte_eth_link { } } #[inline] + pub unsafe fn link_autoneg_raw(this: *const Self) -> u16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_link_autoneg_raw(this: *mut Self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn link_status(&self) -> u16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) } } @@ -209,6 +320,31 @@ impl rte_eth_link { } } #[inline] + pub unsafe fn link_status_raw(this: *const Self) -> u16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_link_status_raw(this: *mut Self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 2usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( link_duplex: u16, link_autoneg: u16, diff --git a/bindgen-tests/tests/expectations/tests/layout_array.rs b/bindgen-tests/tests/expectations/tests/layout_array.rs index b910159beb..3afe1c2dd8 100644 --- a/bindgen-tests/tests/expectations/tests/layout_array.rs +++ b/bindgen-tests/tests/expectations/tests/layout_array.rs @@ -1,4 +1,12 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C, align(8))] +pub struct __BindgenOpaqueArray8(pub T); +impl Default for __BindgenOpaqueArray8<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} pub const RTE_CACHE_LINE_SIZE: u32 = 64; pub const RTE_MEMPOOL_OPS_NAMESIZE: u32 = 32; pub const RTE_MEMPOOL_MAX_OPS_IDX: u32 = 16; @@ -46,7 +54,7 @@ pub type rte_mempool_get_count = ::std::option::Option< /// Structure defining mempool operations structure #[repr(C)] #[repr(align(64))] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct rte_mempool_ops { ///< Name of mempool ops struct. pub name: [::std::os::raw::c_char; 32usize], @@ -61,51 +69,31 @@ pub struct rte_mempool_ops { ///< Get qty of available objs. pub get_count: rte_mempool_get_count, } -#[test] -fn bindgen_test_layout_rte_mempool_ops() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 128usize, - "Size of rte_mempool_ops", - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_mempool_ops"][::std::mem::size_of::() - 128usize]; + [ "Alignment of rte_mempool_ops", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 64usize]; + [ "Offset of field: rte_mempool_ops::name", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).alloc) as usize - ptr as usize }, - 32usize, + ][::std::mem::offset_of!(rte_mempool_ops, name) - 0usize]; + [ "Offset of field: rte_mempool_ops::alloc", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).free) as usize - ptr as usize }, - 40usize, + ][::std::mem::offset_of!(rte_mempool_ops, alloc) - 32usize]; + [ "Offset of field: rte_mempool_ops::free", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).enqueue) as usize - ptr as usize }, - 48usize, + ][::std::mem::offset_of!(rte_mempool_ops, free) - 40usize]; + [ "Offset of field: rte_mempool_ops::enqueue", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dequeue) as usize - ptr as usize }, - 56usize, + ][::std::mem::offset_of!(rte_mempool_ops, enqueue) - 48usize]; + [ "Offset of field: rte_mempool_ops::dequeue", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).get_count) as usize - ptr as usize }, - 64usize, + ][::std::mem::offset_of!(rte_mempool_ops, dequeue) - 56usize]; + [ "Offset of field: rte_mempool_ops::get_count", - ); -} + ][::std::mem::offset_of!(rte_mempool_ops, get_count) - 64usize]; +}; impl Default for rte_mempool_ops { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -115,13 +103,6 @@ impl Default for rte_mempool_ops { } } } -impl ::std::cmp::PartialEq for rte_mempool_ops { - fn eq(&self, other: &rte_mempool_ops) -> bool { - self.name == other.name && self.alloc == other.alloc && self.free == other.free - && self.enqueue == other.enqueue && self.dequeue == other.dequeue - && self.get_count == other.get_count - } -} /// The rte_spinlock_t type. #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] @@ -129,26 +110,14 @@ pub struct rte_spinlock_t { ///< lock status 0 = unlocked, 1 = locked pub locked: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_rte_spinlock_t() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of rte_spinlock_t", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_spinlock_t", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).locked) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_spinlock_t"][::std::mem::size_of::() - 4usize]; + ["Alignment of rte_spinlock_t"][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_spinlock_t::locked", - ); -} + ][::std::mem::offset_of!(rte_spinlock_t, locked) - 0usize]; +}; /** Structure storing the table of registered ops structs, each of which contain the function pointers for the mempool ops functions. Each process has its own storage for this ops struct array so that @@ -158,46 +127,34 @@ fn bindgen_test_layout_rte_spinlock_t() { This results in us simply having "ops_index" in the mempool struct.*/ #[repr(C)] #[repr(align(64))] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct rte_mempool_ops_table { ///< Spinlock for add/delete. pub sl: rte_spinlock_t, ///< Number of used ops structs in the table. pub num_ops: u32, - pub __bindgen_padding_0: [u64; 7usize], + pub __bindgen_padding_0: __BindgenOpaqueArray8<[u8; 56usize]>, /// Storage for all possible ops structs. pub ops: [rte_mempool_ops; 16usize], } -#[test] -fn bindgen_test_layout_rte_mempool_ops_table() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 2112usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_mempool_ops_table", - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, + ][::std::mem::size_of::() - 2112usize]; + [ "Alignment of rte_mempool_ops_table", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).sl) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 64usize]; + [ "Offset of field: rte_mempool_ops_table::sl", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).num_ops) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(rte_mempool_ops_table, sl) - 0usize]; + [ "Offset of field: rte_mempool_ops_table::num_ops", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ops) as usize - ptr as usize }, - 64usize, + ][::std::mem::offset_of!(rte_mempool_ops_table, num_ops) - 4usize]; + [ "Offset of field: rte_mempool_ops_table::ops", - ); -} + ][::std::mem::offset_of!(rte_mempool_ops_table, ops) - 64usize]; +}; impl Default for rte_mempool_ops_table { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -210,7 +167,7 @@ impl Default for rte_mempool_ops_table { /// Structure to hold malloc heap #[repr(C)] #[repr(align(64))] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct malloc_heap { pub lock: rte_spinlock_t, pub free_head: [malloc_heap__bindgen_ty_1; 13usize], @@ -222,26 +179,18 @@ pub struct malloc_heap { pub struct malloc_heap__bindgen_ty_1 { pub lh_first: *mut malloc_elem, } -#[test] -fn bindgen_test_layout_malloc_heap__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of malloc_heap__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, + ][::std::mem::size_of::() - 8usize]; + [ "Alignment of malloc_heap__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).lh_first) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 8usize]; + [ "Offset of field: malloc_heap__bindgen_ty_1::lh_first", - ); -} + ][::std::mem::offset_of!(malloc_heap__bindgen_ty_1, lh_first) - 0usize]; +}; impl Default for malloc_heap__bindgen_ty_1 { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -251,37 +200,23 @@ impl Default for malloc_heap__bindgen_ty_1 { } } } -#[test] -fn bindgen_test_layout_malloc_heap() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 128usize, "Size of malloc_heap"); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - "Alignment of malloc_heap", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).lock) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of malloc_heap"][::std::mem::size_of::() - 128usize]; + ["Alignment of malloc_heap"][::std::mem::align_of::() - 64usize]; + [ "Offset of field: malloc_heap::lock", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).free_head) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(malloc_heap, lock) - 0usize]; + [ "Offset of field: malloc_heap::free_head", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).alloc_count) as usize - ptr as usize }, - 112usize, + ][::std::mem::offset_of!(malloc_heap, free_head) - 8usize]; + [ "Offset of field: malloc_heap::alloc_count", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).total_size) as usize - ptr as usize }, - 120usize, + ][::std::mem::offset_of!(malloc_heap, alloc_count) - 112usize]; + [ "Offset of field: malloc_heap::total_size", - ); -} + ][::std::mem::offset_of!(malloc_heap, total_size) - 120usize]; +}; impl Default for malloc_heap { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -291,13 +226,6 @@ impl Default for malloc_heap { } } } -impl ::std::cmp::PartialEq for malloc_heap { - fn eq(&self, other: &malloc_heap) -> bool { - self.lock == other.lock && self.free_head == other.free_head - && self.alloc_count == other.alloc_count - && self.total_size == other.total_size - } -} #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct malloc_elem { diff --git a/bindgen-tests/tests/expectations/tests/layout_array_too_long.rs b/bindgen-tests/tests/expectations/tests/layout_array_too_long.rs index d6ce2883d7..315663e0fc 100644 --- a/bindgen-tests/tests/expectations/tests/layout_array_too_long.rs +++ b/bindgen-tests/tests/expectations/tests/layout_array_too_long.rs @@ -27,28 +27,14 @@ pub struct ip_frag { ///< fragment mbuf pub mb: *mut rte_mbuf, } -#[test] -fn bindgen_test_layout_ip_frag() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 16usize, "Size of ip_frag"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of ip_frag"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ofs) as usize - ptr as usize }, - 0usize, - "Offset of field: ip_frag::ofs", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).len) as usize - ptr as usize }, - 2usize, - "Offset of field: ip_frag::len", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mb) as usize - ptr as usize }, - 8usize, - "Offset of field: ip_frag::mb", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ip_frag"][::std::mem::size_of::() - 16usize]; + ["Alignment of ip_frag"][::std::mem::align_of::() - 8usize]; + ["Offset of field: ip_frag::ofs"][::std::mem::offset_of!(ip_frag, ofs) - 0usize]; + ["Offset of field: ip_frag::len"][::std::mem::offset_of!(ip_frag, len) - 2usize]; + ["Offset of field: ip_frag::mb"][::std::mem::offset_of!(ip_frag, mb) - 8usize]; +}; impl Default for ip_frag { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -69,37 +55,25 @@ pub struct ip_frag_key { ///< src/dst key length pub key_len: u32, } -#[test] -fn bindgen_test_layout_ip_frag_key() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 40usize, "Size of ip_frag_key"); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of ip_frag_key", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).src_dst) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ip_frag_key"][::std::mem::size_of::() - 40usize]; + ["Alignment of ip_frag_key"][::std::mem::align_of::() - 8usize]; + [ "Offset of field: ip_frag_key::src_dst", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize }, - 32usize, + ][::std::mem::offset_of!(ip_frag_key, src_dst) - 0usize]; + [ "Offset of field: ip_frag_key::id", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).key_len) as usize - ptr as usize }, - 36usize, + ][::std::mem::offset_of!(ip_frag_key, id) - 32usize]; + [ "Offset of field: ip_frag_key::key_len", - ); -} + ][::std::mem::offset_of!(ip_frag_key, key_len) - 36usize]; +}; /** @internal Fragmented packet to reassemble. First two entries in the frags[] array are for the last and first fragments.*/ #[repr(C)] #[repr(align(64))] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct ip_frag_pkt { ///< LRU list pub lru: ip_frag_pkt__bindgen_ty_1, @@ -122,31 +96,21 @@ pub struct ip_frag_pkt__bindgen_ty_1 { pub tqe_next: *mut ip_frag_pkt, pub tqe_prev: *mut *mut ip_frag_pkt, } -#[test] -fn bindgen_test_layout_ip_frag_pkt__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 16usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of ip_frag_pkt__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, + ][::std::mem::size_of::() - 16usize]; + [ "Alignment of ip_frag_pkt__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 8usize]; + [ "Offset of field: ip_frag_pkt__bindgen_ty_1::tqe_next", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(ip_frag_pkt__bindgen_ty_1, tqe_next) - 0usize]; + [ "Offset of field: ip_frag_pkt__bindgen_ty_1::tqe_prev", - ); -} + ][::std::mem::offset_of!(ip_frag_pkt__bindgen_ty_1, tqe_prev) - 8usize]; +}; impl Default for ip_frag_pkt__bindgen_ty_1 { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -156,52 +120,32 @@ impl Default for ip_frag_pkt__bindgen_ty_1 { } } } -#[test] -fn bindgen_test_layout_ip_frag_pkt() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 192usize, "Size of ip_frag_pkt"); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - "Alignment of ip_frag_pkt", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).lru) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ip_frag_pkt"][::std::mem::size_of::() - 192usize]; + ["Alignment of ip_frag_pkt"][::std::mem::align_of::() - 64usize]; + [ "Offset of field: ip_frag_pkt::lru", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).key) as usize - ptr as usize }, - 16usize, + ][::std::mem::offset_of!(ip_frag_pkt, lru) - 0usize]; + [ "Offset of field: ip_frag_pkt::key", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).start) as usize - ptr as usize }, - 56usize, + ][::std::mem::offset_of!(ip_frag_pkt, key) - 16usize]; + [ "Offset of field: ip_frag_pkt::start", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).total_size) as usize - ptr as usize }, - 64usize, + ][::std::mem::offset_of!(ip_frag_pkt, start) - 56usize]; + [ "Offset of field: ip_frag_pkt::total_size", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).frag_size) as usize - ptr as usize }, - 68usize, + ][::std::mem::offset_of!(ip_frag_pkt, total_size) - 64usize]; + [ "Offset of field: ip_frag_pkt::frag_size", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).last_idx) as usize - ptr as usize }, - 72usize, + ][::std::mem::offset_of!(ip_frag_pkt, frag_size) - 68usize]; + [ "Offset of field: ip_frag_pkt::last_idx", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).frags) as usize - ptr as usize }, - 80usize, + ][::std::mem::offset_of!(ip_frag_pkt, last_idx) - 72usize]; + [ "Offset of field: ip_frag_pkt::frags", - ); -} + ][::std::mem::offset_of!(ip_frag_pkt, frags) - 80usize]; +}; impl Default for ip_frag_pkt { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -211,13 +155,6 @@ impl Default for ip_frag_pkt { } } } -impl ::std::cmp::PartialEq for ip_frag_pkt { - fn eq(&self, other: &ip_frag_pkt) -> bool { - self.lru == other.lru && self.key == other.key && self.start == other.start - && self.total_size == other.total_size && self.frag_size == other.frag_size - && self.last_idx == other.last_idx && self.frags == other.frags - } -} ///< fragment mbuf #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] diff --git a/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs b/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs index 9b98bac376..7d975cd979 100644 --- a/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs +++ b/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,6 +126,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } pub const ETH_MQ_RX_RSS_FLAG: u32 = 1; pub const ETH_MQ_RX_DCB_FLAG: u32 = 2; @@ -147,39 +209,22 @@ pub struct rte_eth_rxmode { pub max_rx_pkt_len: u32, ///< hdr buf size (header_split enabled). pub split_hdr_size: u16, - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, } -#[test] -fn bindgen_test_layout_rte_eth_rxmode() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, - "Size of rte_eth_rxmode", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_rxmode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mq_mode) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_eth_rxmode"][::std::mem::size_of::() - 12usize]; + ["Alignment of rte_eth_rxmode"][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_eth_rxmode::mq_mode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).max_rx_pkt_len) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(rte_eth_rxmode, mq_mode) - 0usize]; + [ "Offset of field: rte_eth_rxmode::max_rx_pkt_len", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).split_hdr_size) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(rte_eth_rxmode, max_rx_pkt_len) - 4usize]; + [ "Offset of field: rte_eth_rxmode::split_hdr_size", - ); -} + ][::std::mem::offset_of!(rte_eth_rxmode, split_hdr_size) - 8usize]; +}; impl Default for rte_eth_rxmode { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -202,6 +247,31 @@ impl rte_eth_rxmode { } } #[inline] + pub unsafe fn header_split_raw(this: *const Self) -> u16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_header_split_raw(this: *mut Self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn hw_ip_checksum(&self) -> u16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) } } @@ -213,6 +283,31 @@ impl rte_eth_rxmode { } } #[inline] + pub unsafe fn hw_ip_checksum_raw(this: *const Self) -> u16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_hw_ip_checksum_raw(this: *mut Self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn hw_vlan_filter(&self) -> u16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) } } @@ -224,6 +319,31 @@ impl rte_eth_rxmode { } } #[inline] + pub unsafe fn hw_vlan_filter_raw(this: *const Self) -> u16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_hw_vlan_filter_raw(this: *mut Self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 2usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn hw_vlan_strip(&self) -> u16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u16) } } @@ -235,6 +355,31 @@ impl rte_eth_rxmode { } } #[inline] + pub unsafe fn hw_vlan_strip_raw(this: *const Self) -> u16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 3usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_hw_vlan_strip_raw(this: *mut Self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 3usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn hw_vlan_extend(&self) -> u16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u16) } } @@ -246,6 +391,31 @@ impl rte_eth_rxmode { } } #[inline] + pub unsafe fn hw_vlan_extend_raw(this: *const Self) -> u16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_hw_vlan_extend_raw(this: *mut Self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 4usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn jumbo_frame(&self) -> u16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u16) } } @@ -257,6 +427,31 @@ impl rte_eth_rxmode { } } #[inline] + pub unsafe fn jumbo_frame_raw(this: *const Self) -> u16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 5usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_jumbo_frame_raw(this: *mut Self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 5usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn hw_strip_crc(&self) -> u16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u16) } } @@ -268,6 +463,31 @@ impl rte_eth_rxmode { } } #[inline] + pub unsafe fn hw_strip_crc_raw(this: *const Self) -> u16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 6usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_hw_strip_crc_raw(this: *mut Self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 6usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn enable_scatter(&self) -> u16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u16) } } @@ -279,6 +499,31 @@ impl rte_eth_rxmode { } } #[inline] + pub unsafe fn enable_scatter_raw(this: *const Self) -> u16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 7usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_enable_scatter_raw(this: *mut Self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 7usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn enable_lro(&self) -> u16 { unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u16) } } @@ -290,6 +535,31 @@ impl rte_eth_rxmode { } } #[inline] + pub unsafe fn enable_lro_raw(this: *const Self) -> u16 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 8usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_enable_lro_raw(this: *mut Self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 8usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( header_split: u16, hw_ip_checksum: u16, @@ -421,35 +691,20 @@ pub struct rte_eth_txmode { ///< TX multi-queues mode. pub mq_mode: rte_eth_tx_mq_mode, pub pvid: u16, - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub __bindgen_padding_0: u8, } -#[test] -fn bindgen_test_layout_rte_eth_txmode() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of rte_eth_txmode", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_txmode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mq_mode) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_eth_txmode"][::std::mem::size_of::() - 8usize]; + ["Alignment of rte_eth_txmode"][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_eth_txmode::mq_mode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pvid) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(rte_eth_txmode, mq_mode) - 0usize]; + [ "Offset of field: rte_eth_txmode::pvid", - ); -} + ][::std::mem::offset_of!(rte_eth_txmode, pvid) - 4usize]; +}; impl Default for rte_eth_txmode { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -472,6 +727,30 @@ impl rte_eth_txmode { } } #[inline] + pub unsafe fn hw_vlan_reject_tagged_raw(this: *const Self) -> u8 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_hw_vlan_reject_tagged_raw(this: *mut Self, val: u8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn hw_vlan_reject_untagged(&self) -> u8 { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } } @@ -483,6 +762,30 @@ impl rte_eth_txmode { } } #[inline] + pub unsafe fn hw_vlan_reject_untagged_raw(this: *const Self) -> u8 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_hw_vlan_reject_untagged_raw(this: *mut Self, val: u8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn hw_vlan_insert_pvid(&self) -> u8 { unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u8) } } @@ -494,6 +797,30 @@ impl rte_eth_txmode { } } #[inline] + pub unsafe fn hw_vlan_insert_pvid_raw(this: *const Self) -> u8 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_hw_vlan_insert_pvid_raw(this: *mut Self, val: u8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 2usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( hw_vlan_reject_tagged: u8, hw_vlan_reject_untagged: u8, @@ -561,36 +888,22 @@ pub struct rte_eth_rss_conf { ///< Hash functions to apply - see below. pub rss_hf: u64, } -#[test] -fn bindgen_test_layout_rte_eth_rss_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 24usize, - "Size of rte_eth_rss_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_eth_rss_conf"][::std::mem::size_of::() - 24usize]; + [ "Alignment of rte_eth_rss_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rss_key) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 8usize]; + [ "Offset of field: rte_eth_rss_conf::rss_key", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rss_key_len) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(rte_eth_rss_conf, rss_key) - 0usize]; + [ "Offset of field: rte_eth_rss_conf::rss_key_len", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rss_hf) as usize - ptr as usize }, - 16usize, + ][::std::mem::offset_of!(rte_eth_rss_conf, rss_key_len) - 8usize]; + [ "Offset of field: rte_eth_rss_conf::rss_hf", - ); -} + ][::std::mem::offset_of!(rte_eth_rss_conf, rss_hf) - 16usize]; +}; impl Default for rte_eth_rss_conf { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -634,7 +947,7 @@ pub enum rte_eth_nb_pools { A default pool may be used, if desired, to route all traffic which does not match the vlan filter rules.*/ #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct rte_eth_vmdq_dcb_conf { ///< With DCB, 16 or 32 pools pub nb_queue_pools: rte_eth_nb_pools, @@ -656,78 +969,48 @@ pub struct rte_eth_vmdq_dcb_conf__bindgen_ty_1 { ///< Bitmask of pools for packet rx pub pools: u64, } -#[test] -fn bindgen_test_layout_rte_eth_vmdq_dcb_conf__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 16usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_vmdq_dcb_conf__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, + ][::std::mem::size_of::() - 16usize]; + [ "Alignment of rte_eth_vmdq_dcb_conf__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vlan_id) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 8usize]; + [ "Offset of field: rte_eth_vmdq_dcb_conf__bindgen_ty_1::vlan_id", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pools) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_conf__bindgen_ty_1, vlan_id) - 0usize]; + [ "Offset of field: rte_eth_vmdq_dcb_conf__bindgen_ty_1::pools", - ); -} -#[test] -fn bindgen_test_layout_rte_eth_vmdq_dcb_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 1040usize, + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_conf__bindgen_ty_1, pools) - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_vmdq_dcb_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, + ][::std::mem::size_of::() - 1040usize]; + [ "Alignment of rte_eth_vmdq_dcb_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_queue_pools) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 8usize]; + [ "Offset of field: rte_eth_vmdq_dcb_conf::nb_queue_pools", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).enable_default_pool) as usize - ptr as usize - }, - 4usize, + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_conf, nb_queue_pools) - 0usize]; + [ "Offset of field: rte_eth_vmdq_dcb_conf::enable_default_pool", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).default_pool) as usize - ptr as usize }, - 5usize, + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_conf, enable_default_pool) - 4usize]; + [ "Offset of field: rte_eth_vmdq_dcb_conf::default_pool", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_pool_maps) as usize - ptr as usize }, - 6usize, + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_conf, default_pool) - 5usize]; + [ "Offset of field: rte_eth_vmdq_dcb_conf::nb_pool_maps", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pool_map) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_conf, nb_pool_maps) - 6usize]; + [ "Offset of field: rte_eth_vmdq_dcb_conf::pool_map", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dcb_tc) as usize - ptr as usize }, - 1032usize, + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_conf, pool_map) - 8usize]; + [ "Offset of field: rte_eth_vmdq_dcb_conf::dcb_tc", - ); -} + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_conf, dcb_tc) - 1032usize]; +}; impl Default for rte_eth_vmdq_dcb_conf { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -745,31 +1028,21 @@ pub struct rte_eth_dcb_rx_conf { /// Traffic class each UP mapped to. pub dcb_tc: [u8; 8usize], } -#[test] -fn bindgen_test_layout_rte_eth_dcb_rx_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_dcb_rx_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 12usize]; + [ "Alignment of rte_eth_dcb_rx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_tcs) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_eth_dcb_rx_conf::nb_tcs", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dcb_tc) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(rte_eth_dcb_rx_conf, nb_tcs) - 0usize]; + [ "Offset of field: rte_eth_dcb_rx_conf::dcb_tc", - ); -} + ][::std::mem::offset_of!(rte_eth_dcb_rx_conf, dcb_tc) - 4usize]; +}; impl Default for rte_eth_dcb_rx_conf { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -787,31 +1060,21 @@ pub struct rte_eth_vmdq_dcb_tx_conf { /// Traffic class each UP mapped to. pub dcb_tc: [u8; 8usize], } -#[test] -fn bindgen_test_layout_rte_eth_vmdq_dcb_tx_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_vmdq_dcb_tx_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 12usize]; + [ "Alignment of rte_eth_vmdq_dcb_tx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_queue_pools) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_eth_vmdq_dcb_tx_conf::nb_queue_pools", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dcb_tc) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_tx_conf, nb_queue_pools) - 0usize]; + [ "Offset of field: rte_eth_vmdq_dcb_tx_conf::dcb_tc", - ); -} + ][::std::mem::offset_of!(rte_eth_vmdq_dcb_tx_conf, dcb_tc) - 4usize]; +}; impl Default for rte_eth_vmdq_dcb_tx_conf { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -829,31 +1092,21 @@ pub struct rte_eth_dcb_tx_conf { /// Traffic class each UP mapped to. pub dcb_tc: [u8; 8usize], } -#[test] -fn bindgen_test_layout_rte_eth_dcb_tx_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_dcb_tx_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 12usize]; + [ "Alignment of rte_eth_dcb_tx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_tcs) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_eth_dcb_tx_conf::nb_tcs", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dcb_tc) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(rte_eth_dcb_tx_conf, nb_tcs) - 0usize]; + [ "Offset of field: rte_eth_dcb_tx_conf::dcb_tc", - ); -} + ][::std::mem::offset_of!(rte_eth_dcb_tx_conf, dcb_tc) - 4usize]; +}; impl Default for rte_eth_dcb_tx_conf { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -869,26 +1122,18 @@ pub struct rte_eth_vmdq_tx_conf { ///< VMDq mode, 64 pools. pub nb_queue_pools: rte_eth_nb_pools, } -#[test] -fn bindgen_test_layout_rte_eth_vmdq_tx_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_vmdq_tx_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 4usize]; + [ "Alignment of rte_eth_vmdq_tx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_queue_pools) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_eth_vmdq_tx_conf::nb_queue_pools", - ); -} + ][::std::mem::offset_of!(rte_eth_vmdq_tx_conf, nb_queue_pools) - 0usize]; +}; impl Default for rte_eth_vmdq_tx_conf { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -899,7 +1144,7 @@ impl Default for rte_eth_vmdq_tx_conf { } } #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct rte_eth_vmdq_rx_conf { ///< VMDq only mode, 8 or 64 pools pub nb_queue_pools: rte_eth_nb_pools, @@ -924,83 +1169,51 @@ pub struct rte_eth_vmdq_rx_conf__bindgen_ty_1 { ///< Bitmask of pools for packet rx pub pools: u64, } -#[test] -fn bindgen_test_layout_rte_eth_vmdq_rx_conf__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 16usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_vmdq_rx_conf__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, + ][::std::mem::size_of::() - 16usize]; + [ "Alignment of rte_eth_vmdq_rx_conf__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vlan_id) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 8usize]; + [ "Offset of field: rte_eth_vmdq_rx_conf__bindgen_ty_1::vlan_id", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pools) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf__bindgen_ty_1, vlan_id) - 0usize]; + [ "Offset of field: rte_eth_vmdq_rx_conf__bindgen_ty_1::pools", - ); -} -#[test] -fn bindgen_test_layout_rte_eth_vmdq_rx_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 1040usize, + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf__bindgen_ty_1, pools) - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_vmdq_rx_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, + ][::std::mem::size_of::() - 1040usize]; + [ "Alignment of rte_eth_vmdq_rx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_queue_pools) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 8usize]; + [ "Offset of field: rte_eth_vmdq_rx_conf::nb_queue_pools", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).enable_default_pool) as usize - ptr as usize - }, - 4usize, + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf, nb_queue_pools) - 0usize]; + [ "Offset of field: rte_eth_vmdq_rx_conf::enable_default_pool", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).default_pool) as usize - ptr as usize }, - 5usize, + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf, enable_default_pool) - 4usize]; + [ "Offset of field: rte_eth_vmdq_rx_conf::default_pool", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).enable_loop_back) as usize - ptr as usize }, - 6usize, + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf, default_pool) - 5usize]; + [ "Offset of field: rte_eth_vmdq_rx_conf::enable_loop_back", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_pool_maps) as usize - ptr as usize }, - 7usize, + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf, enable_loop_back) - 6usize]; + [ "Offset of field: rte_eth_vmdq_rx_conf::nb_pool_maps", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rx_mode) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf, nb_pool_maps) - 7usize]; + [ "Offset of field: rte_eth_vmdq_rx_conf::rx_mode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pool_map) as usize - ptr as usize }, - 16usize, + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf, rx_mode) - 8usize]; + [ "Offset of field: rte_eth_vmdq_rx_conf::pool_map", - ); -} + ][::std::mem::offset_of!(rte_eth_vmdq_rx_conf, pool_map) - 16usize]; +}; impl Default for rte_eth_vmdq_rx_conf { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -1063,46 +1276,28 @@ pub struct rte_eth_ipv4_flow { ///< Protocol, next header in big endian. pub proto: u8, } -#[test] -fn bindgen_test_layout_rte_eth_ipv4_flow() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, - "Size of rte_eth_ipv4_flow", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_eth_ipv4_flow"][::std::mem::size_of::() - 12usize]; + [ "Alignment of rte_eth_ipv4_flow", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).src_ip) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_eth_ipv4_flow::src_ip", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dst_ip) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(rte_eth_ipv4_flow, src_ip) - 0usize]; + [ "Offset of field: rte_eth_ipv4_flow::dst_ip", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tos) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(rte_eth_ipv4_flow, dst_ip) - 4usize]; + [ "Offset of field: rte_eth_ipv4_flow::tos", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ttl) as usize - ptr as usize }, - 9usize, + ][::std::mem::offset_of!(rte_eth_ipv4_flow, tos) - 8usize]; + [ "Offset of field: rte_eth_ipv4_flow::ttl", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize }, - 10usize, + ][::std::mem::offset_of!(rte_eth_ipv4_flow, ttl) - 9usize]; + [ "Offset of field: rte_eth_ipv4_flow::proto", - ); -} + ][::std::mem::offset_of!(rte_eth_ipv4_flow, proto) - 10usize]; +}; /// A structure used to define the input for IPV6 flow #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] @@ -1118,46 +1313,28 @@ pub struct rte_eth_ipv6_flow { ///< Hop limits to match. pub hop_limits: u8, } -#[test] -fn bindgen_test_layout_rte_eth_ipv6_flow() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 36usize, - "Size of rte_eth_ipv6_flow", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_eth_ipv6_flow"][::std::mem::size_of::() - 36usize]; + [ "Alignment of rte_eth_ipv6_flow", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).src_ip) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_eth_ipv6_flow::src_ip", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dst_ip) as usize - ptr as usize }, - 16usize, + ][::std::mem::offset_of!(rte_eth_ipv6_flow, src_ip) - 0usize]; + [ "Offset of field: rte_eth_ipv6_flow::dst_ip", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tc) as usize - ptr as usize }, - 32usize, + ][::std::mem::offset_of!(rte_eth_ipv6_flow, dst_ip) - 16usize]; + [ "Offset of field: rte_eth_ipv6_flow::tc", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize }, - 33usize, + ][::std::mem::offset_of!(rte_eth_ipv6_flow, tc) - 32usize]; + [ "Offset of field: rte_eth_ipv6_flow::proto", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).hop_limits) as usize - ptr as usize }, - 34usize, + ][::std::mem::offset_of!(rte_eth_ipv6_flow, proto) - 33usize]; + [ "Offset of field: rte_eth_ipv6_flow::hop_limits", - ); -} + ][::std::mem::offset_of!(rte_eth_ipv6_flow, hop_limits) - 34usize]; +}; /** A structure used to configure FDIR masks that are used by the device to match the various fields of RX packet headers.*/ #[repr(C)] @@ -1182,63 +1359,39 @@ first byte on the wire*/ 0 - Ignore tunnel type.*/ pub tunnel_type_mask: u8, } -#[test] -fn bindgen_test_layout_rte_eth_fdir_masks() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 68usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_fdir_masks", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 68usize]; + [ "Alignment of rte_eth_fdir_masks", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vlan_tci_mask) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_eth_fdir_masks::vlan_tci_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ipv4_mask) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(rte_eth_fdir_masks, vlan_tci_mask) - 0usize]; + [ "Offset of field: rte_eth_fdir_masks::ipv4_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ipv6_mask) as usize - ptr as usize }, - 16usize, + ][::std::mem::offset_of!(rte_eth_fdir_masks, ipv4_mask) - 4usize]; + [ "Offset of field: rte_eth_fdir_masks::ipv6_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).src_port_mask) as usize - ptr as usize }, - 52usize, + ][::std::mem::offset_of!(rte_eth_fdir_masks, ipv6_mask) - 16usize]; + [ "Offset of field: rte_eth_fdir_masks::src_port_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dst_port_mask) as usize - ptr as usize }, - 54usize, + ][::std::mem::offset_of!(rte_eth_fdir_masks, src_port_mask) - 52usize]; + [ "Offset of field: rte_eth_fdir_masks::dst_port_mask", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).mac_addr_byte_mask) as usize - ptr as usize - }, - 56usize, + ][::std::mem::offset_of!(rte_eth_fdir_masks, dst_port_mask) - 54usize]; + [ "Offset of field: rte_eth_fdir_masks::mac_addr_byte_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tunnel_id_mask) as usize - ptr as usize }, - 60usize, + ][::std::mem::offset_of!(rte_eth_fdir_masks, mac_addr_byte_mask) - 56usize]; + [ "Offset of field: rte_eth_fdir_masks::tunnel_id_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tunnel_type_mask) as usize - ptr as usize }, - 64usize, + ][::std::mem::offset_of!(rte_eth_fdir_masks, tunnel_id_mask) - 60usize]; + [ "Offset of field: rte_eth_fdir_masks::tunnel_type_mask", - ); -} + ][::std::mem::offset_of!(rte_eth_fdir_masks, tunnel_type_mask) - 64usize]; +}; #[repr(u32)] /// Payload type #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] @@ -1259,31 +1412,21 @@ pub struct rte_eth_flex_payload_cfg { pub type_: rte_eth_payload_type, pub src_offset: [u16; 16usize], } -#[test] -fn bindgen_test_layout_rte_eth_flex_payload_cfg() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 36usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_flex_payload_cfg", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 36usize]; + [ "Alignment of rte_eth_flex_payload_cfg", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_eth_flex_payload_cfg::type_", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).src_offset) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(rte_eth_flex_payload_cfg, type_) - 0usize]; + [ "Offset of field: rte_eth_flex_payload_cfg::src_offset", - ); -} + ][::std::mem::offset_of!(rte_eth_flex_payload_cfg, src_offset) - 4usize]; +}; impl Default for rte_eth_flex_payload_cfg { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -1301,31 +1444,21 @@ pub struct rte_eth_fdir_flex_mask { pub flow_type: u16, pub mask: [u8; 16usize], } -#[test] -fn bindgen_test_layout_rte_eth_fdir_flex_mask() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 18usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_fdir_flex_mask", - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, + ][::std::mem::size_of::() - 18usize]; + [ "Alignment of rte_eth_fdir_flex_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).flow_type) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 2usize]; + [ "Offset of field: rte_eth_fdir_flex_mask::flow_type", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mask) as usize - ptr as usize }, - 2usize, + ][::std::mem::offset_of!(rte_eth_fdir_flex_mask, flow_type) - 0usize]; + [ "Offset of field: rte_eth_fdir_flex_mask::mask", - ); -} + ][::std::mem::offset_of!(rte_eth_fdir_flex_mask, mask) - 2usize]; +}; /** A structure used to define all flexible payload related setting include flex payload and flex mask*/ #[repr(C)] @@ -1338,41 +1471,27 @@ pub struct rte_eth_fdir_flex_conf { pub flex_set: [rte_eth_flex_payload_cfg; 8usize], pub flex_mask: [rte_eth_fdir_flex_mask; 22usize], } -#[test] -fn bindgen_test_layout_rte_eth_fdir_flex_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 688usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_fdir_flex_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 688usize]; + [ "Alignment of rte_eth_fdir_flex_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_payloads) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_eth_fdir_flex_conf::nb_payloads", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_flexmasks) as usize - ptr as usize }, - 2usize, + ][::std::mem::offset_of!(rte_eth_fdir_flex_conf, nb_payloads) - 0usize]; + [ "Offset of field: rte_eth_fdir_flex_conf::nb_flexmasks", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).flex_set) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(rte_eth_fdir_flex_conf, nb_flexmasks) - 2usize]; + [ "Offset of field: rte_eth_fdir_flex_conf::flex_set", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).flex_mask) as usize - ptr as usize }, - 292usize, + ][::std::mem::offset_of!(rte_eth_fdir_flex_conf, flex_set) - 4usize]; + [ "Offset of field: rte_eth_fdir_flex_conf::flex_mask", - ); -} + ][::std::mem::offset_of!(rte_eth_fdir_flex_conf, flex_mask) - 292usize]; +}; impl Default for rte_eth_fdir_flex_conf { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -1400,51 +1519,29 @@ pub struct rte_fdir_conf { pub mask: rte_eth_fdir_masks, pub flex_conf: rte_eth_fdir_flex_conf, } -#[test] -fn bindgen_test_layout_rte_fdir_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 772usize, - "Size of rte_fdir_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_fdir_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mode) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_fdir_conf"][::std::mem::size_of::() - 772usize]; + ["Alignment of rte_fdir_conf"][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_fdir_conf::mode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pballoc) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(rte_fdir_conf, mode) - 0usize]; + [ "Offset of field: rte_fdir_conf::pballoc", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).status) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(rte_fdir_conf, pballoc) - 4usize]; + [ "Offset of field: rte_fdir_conf::status", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).drop_queue) as usize - ptr as usize }, - 12usize, + ][::std::mem::offset_of!(rte_fdir_conf, status) - 8usize]; + [ "Offset of field: rte_fdir_conf::drop_queue", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mask) as usize - ptr as usize }, - 16usize, + ][::std::mem::offset_of!(rte_fdir_conf, drop_queue) - 12usize]; + [ "Offset of field: rte_fdir_conf::mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).flex_conf) as usize - ptr as usize }, - 84usize, + ][::std::mem::offset_of!(rte_fdir_conf, mask) - 16usize]; + [ "Offset of field: rte_fdir_conf::flex_conf", - ); -} + ][::std::mem::offset_of!(rte_fdir_conf, flex_conf) - 84usize]; +}; impl Default for rte_fdir_conf { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -1463,27 +1560,17 @@ pub struct rte_intr_conf { /// enable/disable rxq interrupt. 0 (default) - disable, 1 enable pub rxq: u16, } -#[test] -fn bindgen_test_layout_rte_intr_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of rte_intr_conf"); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of rte_intr_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).lsc) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_intr_conf"][::std::mem::size_of::() - 4usize]; + ["Alignment of rte_intr_conf"][::std::mem::align_of::() - 2usize]; + [ "Offset of field: rte_intr_conf::lsc", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rxq) as usize - ptr as usize }, - 2usize, + ][::std::mem::offset_of!(rte_intr_conf, lsc) - 0usize]; + [ "Offset of field: rte_intr_conf::rxq", - ); -} + ][::std::mem::offset_of!(rte_intr_conf, rxq) - 2usize]; +}; /** A structure used to configure an Ethernet port. Depending upon the RX multi-queue mode, extra advanced configuration settings may be needed.*/ @@ -1521,7 +1608,7 @@ is needed,and the variable must be set ETH_DCB_PFC_SUPPORT.*/ pub intr_conf: rte_intr_conf, } #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct rte_eth_conf__bindgen_ty_1 { ///< Port RSS configuration pub rss_conf: rte_eth_rss_conf, @@ -1529,41 +1616,27 @@ pub struct rte_eth_conf__bindgen_ty_1 { pub dcb_rx_conf: rte_eth_dcb_rx_conf, pub vmdq_rx_conf: rte_eth_vmdq_rx_conf, } -#[test] -fn bindgen_test_layout_rte_eth_conf__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 2120usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_conf__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, + ][::std::mem::size_of::() - 2120usize]; + [ "Alignment of rte_eth_conf__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rss_conf) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 8usize]; + [ "Offset of field: rte_eth_conf__bindgen_ty_1::rss_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vmdq_dcb_conf) as usize - ptr as usize }, - 24usize, + ][::std::mem::offset_of!(rte_eth_conf__bindgen_ty_1, rss_conf) - 0usize]; + [ "Offset of field: rte_eth_conf__bindgen_ty_1::vmdq_dcb_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dcb_rx_conf) as usize - ptr as usize }, - 1064usize, + ][::std::mem::offset_of!(rte_eth_conf__bindgen_ty_1, vmdq_dcb_conf) - 24usize]; + [ "Offset of field: rte_eth_conf__bindgen_ty_1::dcb_rx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vmdq_rx_conf) as usize - ptr as usize }, - 1080usize, + ][::std::mem::offset_of!(rte_eth_conf__bindgen_ty_1, dcb_rx_conf) - 1064usize]; + [ "Offset of field: rte_eth_conf__bindgen_ty_1::vmdq_rx_conf", - ); -} + ][::std::mem::offset_of!(rte_eth_conf__bindgen_ty_1, vmdq_rx_conf) - 1080usize]; +}; impl Default for rte_eth_conf__bindgen_ty_1 { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -1580,36 +1653,24 @@ pub union rte_eth_conf__bindgen_ty_2 { pub dcb_tx_conf: rte_eth_dcb_tx_conf, pub vmdq_tx_conf: rte_eth_vmdq_tx_conf, } -#[test] -fn bindgen_test_layout_rte_eth_conf__bindgen_ty_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of rte_eth_conf__bindgen_ty_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 12usize]; + [ "Alignment of rte_eth_conf__bindgen_ty_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vmdq_dcb_tx_conf) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: rte_eth_conf__bindgen_ty_2::vmdq_dcb_tx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dcb_tx_conf) as usize - ptr as usize }, - 0usize, + ][::std::mem::offset_of!(rte_eth_conf__bindgen_ty_2, vmdq_dcb_tx_conf) - 0usize]; + [ "Offset of field: rte_eth_conf__bindgen_ty_2::dcb_tx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vmdq_tx_conf) as usize - ptr as usize }, - 0usize, + ][::std::mem::offset_of!(rte_eth_conf__bindgen_ty_2, dcb_tx_conf) - 0usize]; + [ "Offset of field: rte_eth_conf__bindgen_ty_2::vmdq_tx_conf", - ); -} + ][::std::mem::offset_of!(rte_eth_conf__bindgen_ty_2, vmdq_tx_conf) - 0usize]; +}; impl Default for rte_eth_conf__bindgen_ty_2 { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -1619,64 +1680,38 @@ impl Default for rte_eth_conf__bindgen_ty_2 { } } } -#[test] -fn bindgen_test_layout_rte_eth_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 2944usize, "Size of rte_eth_conf"); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of rte_eth_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).link_speeds) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_eth_conf"][::std::mem::size_of::() - 2944usize]; + ["Alignment of rte_eth_conf"][::std::mem::align_of::() - 8usize]; + [ "Offset of field: rte_eth_conf::link_speeds", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rxmode) as usize - ptr as usize }, - 4usize, + ][::std::mem::offset_of!(rte_eth_conf, link_speeds) - 0usize]; + [ "Offset of field: rte_eth_conf::rxmode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).txmode) as usize - ptr as usize }, - 16usize, + ][::std::mem::offset_of!(rte_eth_conf, rxmode) - 4usize]; + [ "Offset of field: rte_eth_conf::txmode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).lpbk_mode) as usize - ptr as usize }, - 24usize, + ][::std::mem::offset_of!(rte_eth_conf, txmode) - 16usize]; + [ "Offset of field: rte_eth_conf::lpbk_mode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rx_adv_conf) as usize - ptr as usize }, - 32usize, + ][::std::mem::offset_of!(rte_eth_conf, lpbk_mode) - 24usize]; + [ "Offset of field: rte_eth_conf::rx_adv_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tx_adv_conf) as usize - ptr as usize }, - 2152usize, + ][::std::mem::offset_of!(rte_eth_conf, rx_adv_conf) - 32usize]; + [ "Offset of field: rte_eth_conf::tx_adv_conf", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).dcb_capability_en) as usize - ptr as usize - }, - 2164usize, + ][::std::mem::offset_of!(rte_eth_conf, tx_adv_conf) - 2152usize]; + [ "Offset of field: rte_eth_conf::dcb_capability_en", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).fdir_conf) as usize - ptr as usize }, - 2168usize, + ][::std::mem::offset_of!(rte_eth_conf, dcb_capability_en) - 2164usize]; + [ "Offset of field: rte_eth_conf::fdir_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).intr_conf) as usize - ptr as usize }, - 2940usize, + ][::std::mem::offset_of!(rte_eth_conf, fdir_conf) - 2168usize]; + [ "Offset of field: rte_eth_conf::intr_conf", - ); -} + ][::std::mem::offset_of!(rte_eth_conf, intr_conf) - 2940usize]; +}; impl Default for rte_eth_conf { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); diff --git a/bindgen-tests/tests/expectations/tests/layout_eth_conf_1_0.rs b/bindgen-tests/tests/expectations/tests/layout_eth_conf_1_0.rs deleted file mode 100644 index 34688b20b3..0000000000 --- a/bindgen-tests/tests/expectations/tests/layout_eth_conf_1_0.rs +++ /dev/null @@ -1,1833 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct __BindgenBitfieldUnit { - storage: Storage, -} -impl __BindgenBitfieldUnit { - #[inline] - pub fn new(storage: Storage) -> Self { - Self { storage } - } -} -impl __BindgenBitfieldUnit -where - Storage: AsRef<[u8]> + AsMut<[u8]>, -{ - #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; - let bit_index = if cfg!(target_endian = "big") { - 7 - (index % 8) - } else { - index % 8 - }; - let mask = 1 << bit_index; - byte & mask == mask - } - #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; - let bit_index = if cfg!(target_endian = "big") { - 7 - (index % 8) - } else { - index % 8 - }; - let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } - } - #[inline] - pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { - debug_assert!(bit_width <= 64); - debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); - debug_assert!( - (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), - ); - let mut val = 0; - for i in 0..(bit_width as usize) { - if self.get_bit(i + bit_offset) { - let index = if cfg!(target_endian = "big") { - bit_width as usize - 1 - i - } else { - i - }; - val |= 1 << index; - } - } - val - } - #[inline] - pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { - debug_assert!(bit_width <= 64); - debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); - debug_assert!( - (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), - ); - for i in 0..(bit_width as usize) { - let mask = 1 << i; - let val_bit_is_set = val & mask == mask; - let index = if cfg!(target_endian = "big") { - bit_width as usize - 1 - i - } else { - i - }; - self.set_bit(index + bit_offset, val_bit_is_set); - } - } -} -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -pub const ETH_MQ_RX_RSS_FLAG: u32 = 1; -pub const ETH_MQ_RX_DCB_FLAG: u32 = 2; -pub const ETH_MQ_RX_VMDQ_FLAG: u32 = 4; -pub const ETH_VMDQ_MAX_VLAN_FILTERS: u32 = 64; -pub const ETH_DCB_NUM_USER_PRIORITIES: u32 = 8; -pub const ETH_VMDQ_DCB_NUM_QUEUES: u32 = 128; -pub const ETH_DCB_NUM_QUEUES: u32 = 128; -pub const RTE_ETH_FDIR_MAX_FLEXLEN: u32 = 16; -pub const RTE_ETH_INSET_SIZE_MAX: u32 = 128; -pub const RTE_ETH_FLOW_UNKNOWN: u32 = 0; -pub const RTE_ETH_FLOW_RAW: u32 = 1; -pub const RTE_ETH_FLOW_IPV4: u32 = 2; -pub const RTE_ETH_FLOW_FRAG_IPV4: u32 = 3; -pub const RTE_ETH_FLOW_NONFRAG_IPV4_TCP: u32 = 4; -pub const RTE_ETH_FLOW_NONFRAG_IPV4_UDP: u32 = 5; -pub const RTE_ETH_FLOW_NONFRAG_IPV4_SCTP: u32 = 6; -pub const RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: u32 = 7; -pub const RTE_ETH_FLOW_IPV6: u32 = 8; -pub const RTE_ETH_FLOW_FRAG_IPV6: u32 = 9; -pub const RTE_ETH_FLOW_NONFRAG_IPV6_TCP: u32 = 10; -pub const RTE_ETH_FLOW_NONFRAG_IPV6_UDP: u32 = 11; -pub const RTE_ETH_FLOW_NONFRAG_IPV6_SCTP: u32 = 12; -pub const RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: u32 = 13; -pub const RTE_ETH_FLOW_L2_PAYLOAD: u32 = 14; -pub const RTE_ETH_FLOW_IPV6_EX: u32 = 15; -pub const RTE_ETH_FLOW_IPV6_TCP_EX: u32 = 16; -pub const RTE_ETH_FLOW_IPV6_UDP_EX: u32 = 17; -pub const RTE_ETH_FLOW_PORT: u32 = 18; -pub const RTE_ETH_FLOW_VXLAN: u32 = 19; -pub const RTE_ETH_FLOW_GENEVE: u32 = 20; -pub const RTE_ETH_FLOW_NVGRE: u32 = 21; -pub const RTE_ETH_FLOW_MAX: u32 = 22; -#[repr(u32)] -/** A set of values to identify what method is to be used to route - packets to multiple queues.*/ -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum rte_eth_rx_mq_mode { - /// None of DCB,RSS or VMDQ mode - ETH_MQ_RX_NONE = 0, - /// For RX side, only RSS is on - ETH_MQ_RX_RSS = 1, - /// For RX side,only DCB is on. - ETH_MQ_RX_DCB = 2, - /// Both DCB and RSS enable - ETH_MQ_RX_DCB_RSS = 3, - /// Only VMDQ, no RSS nor DCB - ETH_MQ_RX_VMDQ_ONLY = 4, - /// RSS mode with VMDQ - ETH_MQ_RX_VMDQ_RSS = 5, - /// Use VMDQ+DCB to route traffic to queues - ETH_MQ_RX_VMDQ_DCB = 6, - /// Enable both VMDQ and DCB in VMDq - ETH_MQ_RX_VMDQ_DCB_RSS = 7, -} -/// A structure used to configure the RX features of an Ethernet port. -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_rxmode { - /// The multi-queue packet distribution mode to be used, e.g. RSS. - pub mq_mode: rte_eth_rx_mq_mode, - ///< Only used if jumbo_frame enabled. - pub max_rx_pkt_len: u32, - ///< hdr buf size (header_split enabled). - pub split_hdr_size: u16, - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, -} -#[test] -fn bindgen_test_layout_rte_eth_rxmode() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, - "Size of rte_eth_rxmode", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_rxmode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mq_mode) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_rxmode::mq_mode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).max_rx_pkt_len) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_eth_rxmode::max_rx_pkt_len", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).split_hdr_size) as usize - ptr as usize }, - 8usize, - "Offset of field: rte_eth_rxmode::split_hdr_size", - ); -} -impl Clone for rte_eth_rxmode { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_rxmode { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -impl rte_eth_rxmode { - #[inline] - pub fn header_split(&self) -> u16 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) } - } - #[inline] - pub fn set_header_split(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 1u8, val as u64) - } - } - #[inline] - pub fn hw_ip_checksum(&self) -> u16 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) } - } - #[inline] - pub fn set_hw_ip_checksum(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(1usize, 1u8, val as u64) - } - } - #[inline] - pub fn hw_vlan_filter(&self) -> u16 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) } - } - #[inline] - pub fn set_hw_vlan_filter(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(2usize, 1u8, val as u64) - } - } - #[inline] - pub fn hw_vlan_strip(&self) -> u16 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u16) } - } - #[inline] - pub fn set_hw_vlan_strip(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(3usize, 1u8, val as u64) - } - } - #[inline] - pub fn hw_vlan_extend(&self) -> u16 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u16) } - } - #[inline] - pub fn set_hw_vlan_extend(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(4usize, 1u8, val as u64) - } - } - #[inline] - pub fn jumbo_frame(&self) -> u16 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 1u8) as u16) } - } - #[inline] - pub fn set_jumbo_frame(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(5usize, 1u8, val as u64) - } - } - #[inline] - pub fn hw_strip_crc(&self) -> u16 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 1u8) as u16) } - } - #[inline] - pub fn set_hw_strip_crc(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(6usize, 1u8, val as u64) - } - } - #[inline] - pub fn enable_scatter(&self) -> u16 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u16) } - } - #[inline] - pub fn set_enable_scatter(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(7usize, 1u8, val as u64) - } - } - #[inline] - pub fn enable_lro(&self) -> u16 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u16) } - } - #[inline] - pub fn set_enable_lro(&mut self, val: u16) { - unsafe { - let val: u16 = ::std::mem::transmute(val); - self._bitfield_1.set(8usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - header_split: u16, - hw_ip_checksum: u16, - hw_vlan_filter: u16, - hw_vlan_strip: u16, - hw_vlan_extend: u16, - jumbo_frame: u16, - hw_strip_crc: u16, - enable_scatter: u16, - enable_lro: u16, - ) -> __BindgenBitfieldUnit<[u8; 2usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); - __bindgen_bitfield_unit - .set( - 0usize, - 1u8, - { - let header_split: u16 = unsafe { - ::std::mem::transmute(header_split) - }; - header_split as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 1usize, - 1u8, - { - let hw_ip_checksum: u16 = unsafe { - ::std::mem::transmute(hw_ip_checksum) - }; - hw_ip_checksum as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 2usize, - 1u8, - { - let hw_vlan_filter: u16 = unsafe { - ::std::mem::transmute(hw_vlan_filter) - }; - hw_vlan_filter as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 3usize, - 1u8, - { - let hw_vlan_strip: u16 = unsafe { - ::std::mem::transmute(hw_vlan_strip) - }; - hw_vlan_strip as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 4usize, - 1u8, - { - let hw_vlan_extend: u16 = unsafe { - ::std::mem::transmute(hw_vlan_extend) - }; - hw_vlan_extend as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 5usize, - 1u8, - { - let jumbo_frame: u16 = unsafe { ::std::mem::transmute(jumbo_frame) }; - jumbo_frame as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 6usize, - 1u8, - { - let hw_strip_crc: u16 = unsafe { - ::std::mem::transmute(hw_strip_crc) - }; - hw_strip_crc as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 7usize, - 1u8, - { - let enable_scatter: u16 = unsafe { - ::std::mem::transmute(enable_scatter) - }; - enable_scatter as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 8usize, - 1u8, - { - let enable_lro: u16 = unsafe { ::std::mem::transmute(enable_lro) }; - enable_lro as u64 - }, - ); - __bindgen_bitfield_unit - } -} -#[repr(u32)] -/** A set of values to identify what method is to be used to transmit - packets using multi-TCs.*/ -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum rte_eth_tx_mq_mode { - ///< It is in neither DCB nor VT mode. - ETH_MQ_TX_NONE = 0, - ///< For TX side,only DCB is on. - ETH_MQ_TX_DCB = 1, - ///< For TX side,both DCB and VT is on. - ETH_MQ_TX_VMDQ_DCB = 2, - ///< Only VT on, no DCB - ETH_MQ_TX_VMDQ_ONLY = 3, -} -/// A structure used to configure the TX features of an Ethernet port. -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_txmode { - ///< TX multi-queues mode. - pub mq_mode: rte_eth_tx_mq_mode, - pub pvid: u16, - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - pub __bindgen_padding_0: u8, -} -#[test] -fn bindgen_test_layout_rte_eth_txmode() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of rte_eth_txmode", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_txmode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mq_mode) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_txmode::mq_mode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pvid) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_eth_txmode::pvid", - ); -} -impl Clone for rte_eth_txmode { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_txmode { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -impl rte_eth_txmode { - #[inline] - pub fn hw_vlan_reject_tagged(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } - } - #[inline] - pub fn set_hw_vlan_reject_tagged(&mut self, val: u8) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 1u8, val as u64) - } - } - #[inline] - pub fn hw_vlan_reject_untagged(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } - } - #[inline] - pub fn set_hw_vlan_reject_untagged(&mut self, val: u8) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(1usize, 1u8, val as u64) - } - } - #[inline] - pub fn hw_vlan_insert_pvid(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u8) } - } - #[inline] - pub fn set_hw_vlan_insert_pvid(&mut self, val: u8) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(2usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - hw_vlan_reject_tagged: u8, - hw_vlan_reject_untagged: u8, - hw_vlan_insert_pvid: u8, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); - __bindgen_bitfield_unit - .set( - 0usize, - 1u8, - { - let hw_vlan_reject_tagged: u8 = unsafe { - ::std::mem::transmute(hw_vlan_reject_tagged) - }; - hw_vlan_reject_tagged as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 1usize, - 1u8, - { - let hw_vlan_reject_untagged: u8 = unsafe { - ::std::mem::transmute(hw_vlan_reject_untagged) - }; - hw_vlan_reject_untagged as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 2usize, - 1u8, - { - let hw_vlan_insert_pvid: u8 = unsafe { - ::std::mem::transmute(hw_vlan_insert_pvid) - }; - hw_vlan_insert_pvid as u64 - }, - ); - __bindgen_bitfield_unit - } -} -/** A structure used to configure the Receive Side Scaling (RSS) feature - of an Ethernet port. - If not NULL, the *rss_key* pointer of the *rss_conf* structure points - to an array holding the RSS key to use for hashing specific header - fields of received packets. The length of this array should be indicated - by *rss_key_len* below. Otherwise, a default random hash key is used by - the device driver. - - The *rss_key_len* field of the *rss_conf* structure indicates the length - in bytes of the array pointed by *rss_key*. To be compatible, this length - will be checked in i40e only. Others assume 40 bytes to be used as before. - - The *rss_hf* field of the *rss_conf* structure indicates the different - types of IPv4/IPv6 packets to which the RSS hashing must be applied. - Supplying an *rss_hf* equal to zero disables the RSS feature.*/ -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_rss_conf { - ///< If not NULL, 40-byte hash key. - pub rss_key: *mut u8, - ///< hash key length in bytes. - pub rss_key_len: u8, - ///< Hash functions to apply - see below. - pub rss_hf: u64, -} -#[test] -fn bindgen_test_layout_rte_eth_rss_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 24usize, - "Size of rte_eth_rss_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of rte_eth_rss_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rss_key) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_rss_conf::rss_key", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rss_key_len) as usize - ptr as usize }, - 8usize, - "Offset of field: rte_eth_rss_conf::rss_key_len", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rss_hf) as usize - ptr as usize }, - 16usize, - "Offset of field: rte_eth_rss_conf::rss_hf", - ); -} -impl Clone for rte_eth_rss_conf { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_rss_conf { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(u32)] -/** This enum indicates the possible number of traffic classes - in DCB configratioins*/ -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum rte_eth_nb_tcs { - ///< 4 TCs with DCB. - ETH_4_TCS = 4, - ///< 8 TCs with DCB. - ETH_8_TCS = 8, -} -#[repr(u32)] -/** This enum indicates the possible number of queue pools - in VMDQ configurations.*/ -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum rte_eth_nb_pools { - ///< 8 VMDq pools. - ETH_8_POOLS = 8, - ///< 16 VMDq pools. - ETH_16_POOLS = 16, - ///< 32 VMDq pools. - ETH_32_POOLS = 32, - ///< 64 VMDq pools. - ETH_64_POOLS = 64, -} -/** A structure used to configure the VMDQ+DCB feature - of an Ethernet port. - - Using this feature, packets are routed to a pool of queues, based - on the vlan ID in the vlan tag, and then to a specific queue within - that pool, using the user priority vlan tag field. - - A default pool may be used, if desired, to route all traffic which - does not match the vlan filter rules.*/ -#[repr(C)] -#[derive(Copy)] -pub struct rte_eth_vmdq_dcb_conf { - ///< With DCB, 16 or 32 pools - pub nb_queue_pools: rte_eth_nb_pools, - ///< If non-zero, use a default pool - pub enable_default_pool: u8, - ///< The default pool, if applicable - pub default_pool: u8, - ///< We can have up to 64 filters/mappings - pub nb_pool_maps: u8, - ///< VMDq vlan pool maps. - pub pool_map: [rte_eth_vmdq_dcb_conf__bindgen_ty_1; 64usize], - pub dcb_tc: [u8; 8usize], -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_vmdq_dcb_conf__bindgen_ty_1 { - ///< The vlan ID of the received frame - pub vlan_id: u16, - ///< Bitmask of pools for packet rx - pub pools: u64, -} -#[test] -fn bindgen_test_layout_rte_eth_vmdq_dcb_conf__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 16usize, - "Size of rte_eth_vmdq_dcb_conf__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of rte_eth_vmdq_dcb_conf__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vlan_id) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_vmdq_dcb_conf__bindgen_ty_1::vlan_id", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pools) as usize - ptr as usize }, - 8usize, - "Offset of field: rte_eth_vmdq_dcb_conf__bindgen_ty_1::pools", - ); -} -impl Clone for rte_eth_vmdq_dcb_conf__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_eth_vmdq_dcb_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 1040usize, - "Size of rte_eth_vmdq_dcb_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of rte_eth_vmdq_dcb_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_queue_pools) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_vmdq_dcb_conf::nb_queue_pools", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).enable_default_pool) as usize - ptr as usize - }, - 4usize, - "Offset of field: rte_eth_vmdq_dcb_conf::enable_default_pool", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).default_pool) as usize - ptr as usize }, - 5usize, - "Offset of field: rte_eth_vmdq_dcb_conf::default_pool", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_pool_maps) as usize - ptr as usize }, - 6usize, - "Offset of field: rte_eth_vmdq_dcb_conf::nb_pool_maps", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pool_map) as usize - ptr as usize }, - 8usize, - "Offset of field: rte_eth_vmdq_dcb_conf::pool_map", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dcb_tc) as usize - ptr as usize }, - 1032usize, - "Offset of field: rte_eth_vmdq_dcb_conf::dcb_tc", - ); -} -impl Clone for rte_eth_vmdq_dcb_conf { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_vmdq_dcb_conf { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_dcb_rx_conf { - ///< Possible DCB TCs, 4 or 8 TCs - pub nb_tcs: rte_eth_nb_tcs, - /// Traffic class each UP mapped to. - pub dcb_tc: [u8; 8usize], -} -#[test] -fn bindgen_test_layout_rte_eth_dcb_rx_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, - "Size of rte_eth_dcb_rx_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_dcb_rx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_tcs) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_dcb_rx_conf::nb_tcs", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dcb_tc) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_eth_dcb_rx_conf::dcb_tc", - ); -} -impl Clone for rte_eth_dcb_rx_conf { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_dcb_rx_conf { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_vmdq_dcb_tx_conf { - ///< With DCB, 16 or 32 pools. - pub nb_queue_pools: rte_eth_nb_pools, - /// Traffic class each UP mapped to. - pub dcb_tc: [u8; 8usize], -} -#[test] -fn bindgen_test_layout_rte_eth_vmdq_dcb_tx_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, - "Size of rte_eth_vmdq_dcb_tx_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_vmdq_dcb_tx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_queue_pools) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_vmdq_dcb_tx_conf::nb_queue_pools", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dcb_tc) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_eth_vmdq_dcb_tx_conf::dcb_tc", - ); -} -impl Clone for rte_eth_vmdq_dcb_tx_conf { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_vmdq_dcb_tx_conf { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_dcb_tx_conf { - ///< Possible DCB TCs, 4 or 8 TCs. - pub nb_tcs: rte_eth_nb_tcs, - /// Traffic class each UP mapped to. - pub dcb_tc: [u8; 8usize], -} -#[test] -fn bindgen_test_layout_rte_eth_dcb_tx_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, - "Size of rte_eth_dcb_tx_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_dcb_tx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_tcs) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_dcb_tx_conf::nb_tcs", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dcb_tc) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_eth_dcb_tx_conf::dcb_tc", - ); -} -impl Clone for rte_eth_dcb_tx_conf { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_dcb_tx_conf { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_vmdq_tx_conf { - ///< VMDq mode, 64 pools. - pub nb_queue_pools: rte_eth_nb_pools, -} -#[test] -fn bindgen_test_layout_rte_eth_vmdq_tx_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of rte_eth_vmdq_tx_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_vmdq_tx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_queue_pools) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_vmdq_tx_conf::nb_queue_pools", - ); -} -impl Clone for rte_eth_vmdq_tx_conf { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_vmdq_tx_conf { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Copy)] -pub struct rte_eth_vmdq_rx_conf { - ///< VMDq only mode, 8 or 64 pools - pub nb_queue_pools: rte_eth_nb_pools, - ///< If non-zero, use a default pool - pub enable_default_pool: u8, - ///< The default pool, if applicable - pub default_pool: u8, - ///< Enable VT loop back - pub enable_loop_back: u8, - ///< We can have up to 64 filters/mappings - pub nb_pool_maps: u8, - ///< Flags from ETH_VMDQ_ACCEPT_* - pub rx_mode: u32, - ///< VMDq vlan pool maps. - pub pool_map: [rte_eth_vmdq_rx_conf__bindgen_ty_1; 64usize], -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_vmdq_rx_conf__bindgen_ty_1 { - ///< The vlan ID of the received frame - pub vlan_id: u16, - ///< Bitmask of pools for packet rx - pub pools: u64, -} -#[test] -fn bindgen_test_layout_rte_eth_vmdq_rx_conf__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 16usize, - "Size of rte_eth_vmdq_rx_conf__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of rte_eth_vmdq_rx_conf__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vlan_id) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_vmdq_rx_conf__bindgen_ty_1::vlan_id", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pools) as usize - ptr as usize }, - 8usize, - "Offset of field: rte_eth_vmdq_rx_conf__bindgen_ty_1::pools", - ); -} -impl Clone for rte_eth_vmdq_rx_conf__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_eth_vmdq_rx_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 1040usize, - "Size of rte_eth_vmdq_rx_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of rte_eth_vmdq_rx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_queue_pools) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_vmdq_rx_conf::nb_queue_pools", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).enable_default_pool) as usize - ptr as usize - }, - 4usize, - "Offset of field: rte_eth_vmdq_rx_conf::enable_default_pool", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).default_pool) as usize - ptr as usize }, - 5usize, - "Offset of field: rte_eth_vmdq_rx_conf::default_pool", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).enable_loop_back) as usize - ptr as usize }, - 6usize, - "Offset of field: rte_eth_vmdq_rx_conf::enable_loop_back", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_pool_maps) as usize - ptr as usize }, - 7usize, - "Offset of field: rte_eth_vmdq_rx_conf::nb_pool_maps", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rx_mode) as usize - ptr as usize }, - 8usize, - "Offset of field: rte_eth_vmdq_rx_conf::rx_mode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pool_map) as usize - ptr as usize }, - 16usize, - "Offset of field: rte_eth_vmdq_rx_conf::pool_map", - ); -} -impl Clone for rte_eth_vmdq_rx_conf { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_vmdq_rx_conf { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(u32)] -/// Flow Director setting modes: none, signature or perfect. -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum rte_fdir_mode { - ///< Disable FDIR support. - RTE_FDIR_MODE_NONE = 0, - ///< Enable FDIR signature filter mode. - RTE_FDIR_MODE_SIGNATURE = 1, - ///< Enable FDIR perfect filter mode. - RTE_FDIR_MODE_PERFECT = 2, - ///< Enable FDIR filter mode - MAC VLAN. - RTE_FDIR_MODE_PERFECT_MAC_VLAN = 3, - ///< Enable FDIR filter mode - tunnel. - RTE_FDIR_MODE_PERFECT_TUNNEL = 4, -} -#[repr(u32)] -/** Memory space that can be configured to store Flow Director filters - in the board memory.*/ -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum rte_fdir_pballoc_type { - ///< 64k. - RTE_FDIR_PBALLOC_64K = 0, - ///< 128k. - RTE_FDIR_PBALLOC_128K = 1, - ///< 256k. - RTE_FDIR_PBALLOC_256K = 2, -} -#[repr(u32)] -/// Select report mode of FDIR hash information in RX descriptors. -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum rte_fdir_status_mode { - ///< Never report FDIR hash. - RTE_FDIR_NO_REPORT_STATUS = 0, - ///< Only report FDIR hash for matching pkts. - RTE_FDIR_REPORT_STATUS = 1, - ///< Always report FDIR hash. - RTE_FDIR_REPORT_STATUS_ALWAYS = 2, -} -/// A structure used to define the input for IPV4 flow -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_ipv4_flow { - ///< IPv4 source address in big endian. - pub src_ip: u32, - ///< IPv4 destination address in big endian. - pub dst_ip: u32, - ///< Type of service to match. - pub tos: u8, - ///< Time to live to match. - pub ttl: u8, - ///< Protocol, next header in big endian. - pub proto: u8, -} -#[test] -fn bindgen_test_layout_rte_eth_ipv4_flow() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, - "Size of rte_eth_ipv4_flow", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_ipv4_flow", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).src_ip) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_ipv4_flow::src_ip", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dst_ip) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_eth_ipv4_flow::dst_ip", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tos) as usize - ptr as usize }, - 8usize, - "Offset of field: rte_eth_ipv4_flow::tos", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ttl) as usize - ptr as usize }, - 9usize, - "Offset of field: rte_eth_ipv4_flow::ttl", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize }, - 10usize, - "Offset of field: rte_eth_ipv4_flow::proto", - ); -} -impl Clone for rte_eth_ipv4_flow { - fn clone(&self) -> Self { - *self - } -} -/// A structure used to define the input for IPV6 flow -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_ipv6_flow { - ///< IPv6 source address in big endian. - pub src_ip: [u32; 4usize], - ///< IPv6 destination address in big endian. - pub dst_ip: [u32; 4usize], - ///< Traffic class to match. - pub tc: u8, - ///< Protocol, next header to match. - pub proto: u8, - ///< Hop limits to match. - pub hop_limits: u8, -} -#[test] -fn bindgen_test_layout_rte_eth_ipv6_flow() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 36usize, - "Size of rte_eth_ipv6_flow", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_ipv6_flow", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).src_ip) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_ipv6_flow::src_ip", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dst_ip) as usize - ptr as usize }, - 16usize, - "Offset of field: rte_eth_ipv6_flow::dst_ip", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tc) as usize - ptr as usize }, - 32usize, - "Offset of field: rte_eth_ipv6_flow::tc", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).proto) as usize - ptr as usize }, - 33usize, - "Offset of field: rte_eth_ipv6_flow::proto", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).hop_limits) as usize - ptr as usize }, - 34usize, - "Offset of field: rte_eth_ipv6_flow::hop_limits", - ); -} -impl Clone for rte_eth_ipv6_flow { - fn clone(&self) -> Self { - *self - } -} -/** A structure used to configure FDIR masks that are used by the device - to match the various fields of RX packet headers.*/ -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_fdir_masks { - ///< Bit mask for vlan_tci in big endian - pub vlan_tci_mask: u16, - /// Bit mask for ipv4 flow in big endian. - pub ipv4_mask: rte_eth_ipv4_flow, - /// Bit maks for ipv6 flow in big endian. - pub ipv6_mask: rte_eth_ipv6_flow, - /// Bit mask for L4 source port in big endian. - pub src_port_mask: u16, - /// Bit mask for L4 destination port in big endian. - pub dst_port_mask: u16, - /** 6 bit mask for proper 6 bytes of Mac address, bit 0 matches the -first byte on the wire*/ - pub mac_addr_byte_mask: u8, - /// Bit mask for tunnel ID in big endian. - pub tunnel_id_mask: u32, - /**< 1 - Match tunnel type, -0 - Ignore tunnel type.*/ - pub tunnel_type_mask: u8, -} -#[test] -fn bindgen_test_layout_rte_eth_fdir_masks() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 68usize, - "Size of rte_eth_fdir_masks", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_fdir_masks", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vlan_tci_mask) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_fdir_masks::vlan_tci_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ipv4_mask) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_eth_fdir_masks::ipv4_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ipv6_mask) as usize - ptr as usize }, - 16usize, - "Offset of field: rte_eth_fdir_masks::ipv6_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).src_port_mask) as usize - ptr as usize }, - 52usize, - "Offset of field: rte_eth_fdir_masks::src_port_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dst_port_mask) as usize - ptr as usize }, - 54usize, - "Offset of field: rte_eth_fdir_masks::dst_port_mask", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).mac_addr_byte_mask) as usize - ptr as usize - }, - 56usize, - "Offset of field: rte_eth_fdir_masks::mac_addr_byte_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tunnel_id_mask) as usize - ptr as usize }, - 60usize, - "Offset of field: rte_eth_fdir_masks::tunnel_id_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tunnel_type_mask) as usize - ptr as usize }, - 64usize, - "Offset of field: rte_eth_fdir_masks::tunnel_type_mask", - ); -} -impl Clone for rte_eth_fdir_masks { - fn clone(&self) -> Self { - *self - } -} -#[repr(u32)] -/// Payload type -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum rte_eth_payload_type { - RTE_ETH_PAYLOAD_UNKNOWN = 0, - RTE_ETH_RAW_PAYLOAD = 1, - RTE_ETH_L2_PAYLOAD = 2, - RTE_ETH_L3_PAYLOAD = 3, - RTE_ETH_L4_PAYLOAD = 4, - RTE_ETH_PAYLOAD_MAX = 8, -} -/** A structure used to select bytes extracted from the protocol layers to - flexible payload for filter*/ -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_flex_payload_cfg { - ///< Payload type - pub type_: rte_eth_payload_type, - pub src_offset: [u16; 16usize], -} -#[test] -fn bindgen_test_layout_rte_eth_flex_payload_cfg() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 36usize, - "Size of rte_eth_flex_payload_cfg", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_flex_payload_cfg", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_flex_payload_cfg::type_", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).src_offset) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_eth_flex_payload_cfg::src_offset", - ); -} -impl Clone for rte_eth_flex_payload_cfg { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_flex_payload_cfg { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -/** A structure used to define FDIR masks for flexible payload - for each flow type*/ -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_fdir_flex_mask { - pub flow_type: u16, - pub mask: [u8; 16usize], -} -#[test] -fn bindgen_test_layout_rte_eth_fdir_flex_mask() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 18usize, - "Size of rte_eth_fdir_flex_mask", - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of rte_eth_fdir_flex_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).flow_type) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_fdir_flex_mask::flow_type", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mask) as usize - ptr as usize }, - 2usize, - "Offset of field: rte_eth_fdir_flex_mask::mask", - ); -} -impl Clone for rte_eth_fdir_flex_mask { - fn clone(&self) -> Self { - *self - } -} -/** A structure used to define all flexible payload related setting - include flex payload and flex mask*/ -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_fdir_flex_conf { - ///< The number of following payload cfg - pub nb_payloads: u16, - ///< The number of following mask - pub nb_flexmasks: u16, - pub flex_set: [rte_eth_flex_payload_cfg; 8usize], - pub flex_mask: [rte_eth_fdir_flex_mask; 22usize], -} -#[test] -fn bindgen_test_layout_rte_eth_fdir_flex_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 688usize, - "Size of rte_eth_fdir_flex_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_fdir_flex_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_payloads) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_fdir_flex_conf::nb_payloads", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_flexmasks) as usize - ptr as usize }, - 2usize, - "Offset of field: rte_eth_fdir_flex_conf::nb_flexmasks", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).flex_set) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_eth_fdir_flex_conf::flex_set", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).flex_mask) as usize - ptr as usize }, - 292usize, - "Offset of field: rte_eth_fdir_flex_conf::flex_mask", - ); -} -impl Clone for rte_eth_fdir_flex_conf { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_fdir_flex_conf { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -/** A structure used to configure the Flow Director (FDIR) feature - of an Ethernet port. - - If mode is RTE_FDIR_DISABLE, the pballoc value is ignored.*/ -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct rte_fdir_conf { - ///< Flow Director mode. - pub mode: rte_fdir_mode, - ///< Space for FDIR filters. - pub pballoc: rte_fdir_pballoc_type, - ///< How to report FDIR hash. - pub status: rte_fdir_status_mode, - /// RX queue of packets matching a "drop" filter in perfect mode. - pub drop_queue: u8, - pub mask: rte_eth_fdir_masks, - pub flex_conf: rte_eth_fdir_flex_conf, -} -#[test] -fn bindgen_test_layout_rte_fdir_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 772usize, - "Size of rte_fdir_conf", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_fdir_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mode) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_fdir_conf::mode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pballoc) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_fdir_conf::pballoc", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).status) as usize - ptr as usize }, - 8usize, - "Offset of field: rte_fdir_conf::status", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).drop_queue) as usize - ptr as usize }, - 12usize, - "Offset of field: rte_fdir_conf::drop_queue", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mask) as usize - ptr as usize }, - 16usize, - "Offset of field: rte_fdir_conf::mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).flex_conf) as usize - ptr as usize }, - 84usize, - "Offset of field: rte_fdir_conf::flex_conf", - ); -} -impl Clone for rte_fdir_conf { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_fdir_conf { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -/// A structure used to enable/disable specific device interrupts. -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_intr_conf { - /// enable/disable lsc interrupt. 0 (default) - disable, 1 enable - pub lsc: u16, - /// enable/disable rxq interrupt. 0 (default) - disable, 1 enable - pub rxq: u16, -} -#[test] -fn bindgen_test_layout_rte_intr_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of rte_intr_conf"); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of rte_intr_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).lsc) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_intr_conf::lsc", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rxq) as usize - ptr as usize }, - 2usize, - "Offset of field: rte_intr_conf::rxq", - ); -} -impl Clone for rte_intr_conf { - fn clone(&self) -> Self { - *self - } -} -/** A structure used to configure an Ethernet port. - Depending upon the RX multi-queue mode, extra advanced - configuration settings may be needed.*/ -#[repr(C)] -#[derive(Copy)] -pub struct rte_eth_conf { - /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be -used. ETH_LINK_SPEED_FIXED disables link -autonegotiation, and a unique speed shall be -set. Otherwise, the bitmap defines the set of -speeds to be advertised. If the special value -ETH_LINK_SPEED_AUTONEG (0) is used, all speeds -supported are advertised.*/ - pub link_speeds: u32, - ///< Port RX configuration. - pub rxmode: rte_eth_rxmode, - ///< Port TX configuration. - pub txmode: rte_eth_txmode, - /**< Loopback operation mode. By default the value -is 0, meaning the loopback mode is disabled. -Read the datasheet of given ethernet controller -for details. The possible values of this field -are defined in implementation of each driver.*/ - pub lpbk_mode: u32, - ///< Port RX filtering configuration (union). - pub rx_adv_conf: rte_eth_conf__bindgen_ty_1, - ///< Port TX DCB configuration (union). - pub tx_adv_conf: rte_eth_conf__bindgen_ty_2, - /** Currently,Priority Flow Control(PFC) are supported,if DCB with PFC -is needed,and the variable must be set ETH_DCB_PFC_SUPPORT.*/ - pub dcb_capability_en: u32, - ///< FDIR configuration. - pub fdir_conf: rte_fdir_conf, - ///< Interrupt mode configuration. - pub intr_conf: rte_intr_conf, -} -#[repr(C)] -#[derive(Copy)] -pub struct rte_eth_conf__bindgen_ty_1 { - ///< Port RSS configuration - pub rss_conf: rte_eth_rss_conf, - pub vmdq_dcb_conf: rte_eth_vmdq_dcb_conf, - pub dcb_rx_conf: rte_eth_dcb_rx_conf, - pub vmdq_rx_conf: rte_eth_vmdq_rx_conf, -} -#[test] -fn bindgen_test_layout_rte_eth_conf__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 2120usize, - "Size of rte_eth_conf__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of rte_eth_conf__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rss_conf) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_conf__bindgen_ty_1::rss_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vmdq_dcb_conf) as usize - ptr as usize }, - 24usize, - "Offset of field: rte_eth_conf__bindgen_ty_1::vmdq_dcb_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dcb_rx_conf) as usize - ptr as usize }, - 1064usize, - "Offset of field: rte_eth_conf__bindgen_ty_1::dcb_rx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vmdq_rx_conf) as usize - ptr as usize }, - 1080usize, - "Offset of field: rte_eth_conf__bindgen_ty_1::vmdq_rx_conf", - ); -} -impl Clone for rte_eth_conf__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_conf__bindgen_ty_1 { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_eth_conf__bindgen_ty_2 { - pub vmdq_dcb_tx_conf: __BindgenUnionField, - pub dcb_tx_conf: __BindgenUnionField, - pub vmdq_tx_conf: __BindgenUnionField, - pub bindgen_union_field: [u32; 3usize], -} -#[test] -fn bindgen_test_layout_rte_eth_conf__bindgen_ty_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 12usize, - "Size of rte_eth_conf__bindgen_ty_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_eth_conf__bindgen_ty_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vmdq_dcb_tx_conf) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_conf__bindgen_ty_2::vmdq_dcb_tx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).dcb_tx_conf) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_conf__bindgen_ty_2::dcb_tx_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vmdq_tx_conf) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_conf__bindgen_ty_2::vmdq_tx_conf", - ); -} -impl Clone for rte_eth_conf__bindgen_ty_2 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_eth_conf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 2944usize, "Size of rte_eth_conf"); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of rte_eth_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).link_speeds) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_eth_conf::link_speeds", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rxmode) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_eth_conf::rxmode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).txmode) as usize - ptr as usize }, - 16usize, - "Offset of field: rte_eth_conf::txmode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).lpbk_mode) as usize - ptr as usize }, - 24usize, - "Offset of field: rte_eth_conf::lpbk_mode", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rx_adv_conf) as usize - ptr as usize }, - 32usize, - "Offset of field: rte_eth_conf::rx_adv_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tx_adv_conf) as usize - ptr as usize }, - 2152usize, - "Offset of field: rte_eth_conf::tx_adv_conf", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).dcb_capability_en) as usize - ptr as usize - }, - 2164usize, - "Offset of field: rte_eth_conf::dcb_capability_en", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).fdir_conf) as usize - ptr as usize }, - 2168usize, - "Offset of field: rte_eth_conf::fdir_conf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).intr_conf) as usize - ptr as usize }, - 2940usize, - "Offset of field: rte_eth_conf::intr_conf", - ); -} -impl Clone for rte_eth_conf { - fn clone(&self) -> Self { - *self - } -} -impl Default for rte_eth_conf { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} diff --git a/bindgen-tests/tests/expectations/tests/layout_kni_mbuf.rs b/bindgen-tests/tests/expectations/tests/layout_kni_mbuf.rs index a9d779e9a1..38f49fb4f0 100644 --- a/bindgen-tests/tests/expectations/tests/layout_kni_mbuf.rs +++ b/bindgen-tests/tests/expectations/tests/layout_kni_mbuf.rs @@ -3,7 +3,7 @@ pub const RTE_CACHE_LINE_MIN_SIZE: u32 = 64; pub const RTE_CACHE_LINE_SIZE: u32 = 64; #[repr(C)] #[repr(align(64))] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct rte_kni_mbuf { pub buf_addr: *mut ::std::os::raw::c_void, pub buf_physaddr: u64, @@ -26,87 +26,53 @@ pub struct rte_kni_mbuf { pub pool: *mut ::std::os::raw::c_void, pub next: *mut ::std::os::raw::c_void, } -#[test] -fn bindgen_test_layout_rte_kni_mbuf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 128usize, "Size of rte_kni_mbuf"); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - "Alignment of rte_kni_mbuf", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).buf_addr) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_kni_mbuf"][::std::mem::size_of::() - 128usize]; + ["Alignment of rte_kni_mbuf"][::std::mem::align_of::() - 64usize]; + [ "Offset of field: rte_kni_mbuf::buf_addr", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).buf_physaddr) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(rte_kni_mbuf, buf_addr) - 0usize]; + [ "Offset of field: rte_kni_mbuf::buf_physaddr", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pad0) as usize - ptr as usize }, - 16usize, + ][::std::mem::offset_of!(rte_kni_mbuf, buf_physaddr) - 8usize]; + [ "Offset of field: rte_kni_mbuf::pad0", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).data_off) as usize - ptr as usize }, - 18usize, + ][::std::mem::offset_of!(rte_kni_mbuf, pad0) - 16usize]; + [ "Offset of field: rte_kni_mbuf::data_off", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pad1) as usize - ptr as usize }, - 20usize, + ][::std::mem::offset_of!(rte_kni_mbuf, data_off) - 18usize]; + [ "Offset of field: rte_kni_mbuf::pad1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_segs) as usize - ptr as usize }, - 22usize, + ][::std::mem::offset_of!(rte_kni_mbuf, pad1) - 20usize]; + [ "Offset of field: rte_kni_mbuf::nb_segs", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pad4) as usize - ptr as usize }, - 23usize, + ][::std::mem::offset_of!(rte_kni_mbuf, nb_segs) - 22usize]; + [ "Offset of field: rte_kni_mbuf::pad4", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ol_flags) as usize - ptr as usize }, - 24usize, + ][::std::mem::offset_of!(rte_kni_mbuf, pad4) - 23usize]; + [ "Offset of field: rte_kni_mbuf::ol_flags", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pad2) as usize - ptr as usize }, - 32usize, + ][::std::mem::offset_of!(rte_kni_mbuf, ol_flags) - 24usize]; + [ "Offset of field: rte_kni_mbuf::pad2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pkt_len) as usize - ptr as usize }, - 36usize, + ][::std::mem::offset_of!(rte_kni_mbuf, pad2) - 32usize]; + [ "Offset of field: rte_kni_mbuf::pkt_len", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).data_len) as usize - ptr as usize }, - 40usize, + ][::std::mem::offset_of!(rte_kni_mbuf, pkt_len) - 36usize]; + [ "Offset of field: rte_kni_mbuf::data_len", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pad3) as usize - ptr as usize }, - 64usize, + ][::std::mem::offset_of!(rte_kni_mbuf, data_len) - 40usize]; + [ "Offset of field: rte_kni_mbuf::pad3", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pool) as usize - ptr as usize }, - 72usize, + ][::std::mem::offset_of!(rte_kni_mbuf, pad3) - 64usize]; + [ "Offset of field: rte_kni_mbuf::pool", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).next) as usize - ptr as usize }, - 80usize, + ][::std::mem::offset_of!(rte_kni_mbuf, pool) - 72usize]; + [ "Offset of field: rte_kni_mbuf::next", - ); -} + ][::std::mem::offset_of!(rte_kni_mbuf, next) - 80usize]; +}; impl Default for rte_kni_mbuf { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); diff --git a/bindgen-tests/tests/expectations/tests/layout_large_align_field.rs b/bindgen-tests/tests/expectations/tests/layout_large_align_field.rs index b72c221dca..0ccd40a5f8 100644 --- a/bindgen-tests/tests/expectations/tests/layout_large_align_field.rs +++ b/bindgen-tests/tests/expectations/tests/layout_large_align_field.rs @@ -1,4 +1,12 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C, align(8))] +pub struct __BindgenOpaqueArray8(pub T); +impl Default for __BindgenOpaqueArray8<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} #[repr(C)] #[derive(Default)] pub struct __IncompleteArrayField(::std::marker::PhantomData, [T; 0]); @@ -57,28 +65,14 @@ pub struct ip_frag { ///< fragment mbuf pub mb: *mut rte_mbuf, } -#[test] -fn bindgen_test_layout_ip_frag() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 16usize, "Size of ip_frag"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of ip_frag"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ofs) as usize - ptr as usize }, - 0usize, - "Offset of field: ip_frag::ofs", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).len) as usize - ptr as usize }, - 2usize, - "Offset of field: ip_frag::len", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mb) as usize - ptr as usize }, - 8usize, - "Offset of field: ip_frag::mb", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ip_frag"][::std::mem::size_of::() - 16usize]; + ["Alignment of ip_frag"][::std::mem::align_of::() - 8usize]; + ["Offset of field: ip_frag::ofs"][::std::mem::offset_of!(ip_frag, ofs) - 0usize]; + ["Offset of field: ip_frag::len"][::std::mem::offset_of!(ip_frag, len) - 2usize]; + ["Offset of field: ip_frag::mb"][::std::mem::offset_of!(ip_frag, mb) - 8usize]; +}; impl Default for ip_frag { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -99,37 +93,25 @@ pub struct ip_frag_key { ///< src/dst key length pub key_len: u32, } -#[test] -fn bindgen_test_layout_ip_frag_key() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 40usize, "Size of ip_frag_key"); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of ip_frag_key", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).src_dst) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ip_frag_key"][::std::mem::size_of::() - 40usize]; + ["Alignment of ip_frag_key"][::std::mem::align_of::() - 8usize]; + [ "Offset of field: ip_frag_key::src_dst", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize }, - 32usize, + ][::std::mem::offset_of!(ip_frag_key, src_dst) - 0usize]; + [ "Offset of field: ip_frag_key::id", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).key_len) as usize - ptr as usize }, - 36usize, + ][::std::mem::offset_of!(ip_frag_key, id) - 32usize]; + [ "Offset of field: ip_frag_key::key_len", - ); -} + ][::std::mem::offset_of!(ip_frag_key, key_len) - 36usize]; +}; /** @internal Fragmented packet to reassemble. First two entries in the frags[] array are for the last and first fragments.*/ #[repr(C)] #[repr(align(64))] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct ip_frag_pkt { ///< LRU list pub lru: ip_frag_pkt__bindgen_ty_1, @@ -152,31 +134,21 @@ pub struct ip_frag_pkt__bindgen_ty_1 { pub tqe_next: *mut ip_frag_pkt, pub tqe_prev: *mut *mut ip_frag_pkt, } -#[test] -fn bindgen_test_layout_ip_frag_pkt__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 16usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of ip_frag_pkt__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, + ][::std::mem::size_of::() - 16usize]; + [ "Alignment of ip_frag_pkt__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tqe_next) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 8usize]; + [ "Offset of field: ip_frag_pkt__bindgen_ty_1::tqe_next", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tqe_prev) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(ip_frag_pkt__bindgen_ty_1, tqe_next) - 0usize]; + [ "Offset of field: ip_frag_pkt__bindgen_ty_1::tqe_prev", - ); -} + ][::std::mem::offset_of!(ip_frag_pkt__bindgen_ty_1, tqe_prev) - 8usize]; +}; impl Default for ip_frag_pkt__bindgen_ty_1 { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -186,52 +158,32 @@ impl Default for ip_frag_pkt__bindgen_ty_1 { } } } -#[test] -fn bindgen_test_layout_ip_frag_pkt() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 192usize, "Size of ip_frag_pkt"); - assert_eq!( - ::std::mem::align_of::(), - 64usize, - "Alignment of ip_frag_pkt", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).lru) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ip_frag_pkt"][::std::mem::size_of::() - 192usize]; + ["Alignment of ip_frag_pkt"][::std::mem::align_of::() - 64usize]; + [ "Offset of field: ip_frag_pkt::lru", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).key) as usize - ptr as usize }, - 16usize, + ][::std::mem::offset_of!(ip_frag_pkt, lru) - 0usize]; + [ "Offset of field: ip_frag_pkt::key", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).start) as usize - ptr as usize }, - 56usize, + ][::std::mem::offset_of!(ip_frag_pkt, key) - 16usize]; + [ "Offset of field: ip_frag_pkt::start", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).total_size) as usize - ptr as usize }, - 64usize, + ][::std::mem::offset_of!(ip_frag_pkt, start) - 56usize]; + [ "Offset of field: ip_frag_pkt::total_size", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).frag_size) as usize - ptr as usize }, - 68usize, + ][::std::mem::offset_of!(ip_frag_pkt, total_size) - 64usize]; + [ "Offset of field: ip_frag_pkt::frag_size", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).last_idx) as usize - ptr as usize }, - 72usize, + ][::std::mem::offset_of!(ip_frag_pkt, frag_size) - 68usize]; + [ "Offset of field: ip_frag_pkt::last_idx", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).frags) as usize - ptr as usize }, - 80usize, + ][::std::mem::offset_of!(ip_frag_pkt, last_idx) - 72usize]; + [ "Offset of field: ip_frag_pkt::frags", - ); -} + ][::std::mem::offset_of!(ip_frag_pkt, frags) - 80usize]; +}; impl Default for ip_frag_pkt { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -247,27 +199,17 @@ pub struct ip_pkt_list { pub tqh_first: *mut ip_frag_pkt, pub tqh_last: *mut *mut ip_frag_pkt, } -#[test] -fn bindgen_test_layout_ip_pkt_list() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 16usize, "Size of ip_pkt_list"); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of ip_pkt_list", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tqh_first) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ip_pkt_list"][::std::mem::size_of::() - 16usize]; + ["Alignment of ip_pkt_list"][::std::mem::align_of::() - 8usize]; + [ "Offset of field: ip_pkt_list::tqh_first", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tqh_last) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(ip_pkt_list, tqh_first) - 0usize]; + [ "Offset of field: ip_pkt_list::tqh_last", - ); -} + ][::std::mem::offset_of!(ip_pkt_list, tqh_last) - 8usize]; +}; impl Default for ip_pkt_list { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -280,7 +222,7 @@ impl Default for ip_pkt_list { /// fragmentation table statistics #[repr(C)] #[repr(align(64))] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct ip_frag_tbl_stat { ///< total # of find/insert attempts. pub find_num: u64, @@ -295,51 +237,31 @@ pub struct ip_frag_tbl_stat { ///< # of 'no space' add failures. pub fail_nospace: u64, } -#[test] -fn bindgen_test_layout_ip_frag_tbl_stat() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 64usize, - "Size of ip_frag_tbl_stat", - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ip_frag_tbl_stat"][::std::mem::size_of::() - 64usize]; + [ "Alignment of ip_frag_tbl_stat", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).find_num) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 64usize]; + [ "Offset of field: ip_frag_tbl_stat::find_num", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).add_num) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(ip_frag_tbl_stat, find_num) - 0usize]; + [ "Offset of field: ip_frag_tbl_stat::add_num", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).del_num) as usize - ptr as usize }, - 16usize, + ][::std::mem::offset_of!(ip_frag_tbl_stat, add_num) - 8usize]; + [ "Offset of field: ip_frag_tbl_stat::del_num", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).reuse_num) as usize - ptr as usize }, - 24usize, + ][::std::mem::offset_of!(ip_frag_tbl_stat, del_num) - 16usize]; + [ "Offset of field: ip_frag_tbl_stat::reuse_num", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).fail_total) as usize - ptr as usize }, - 32usize, + ][::std::mem::offset_of!(ip_frag_tbl_stat, reuse_num) - 24usize]; + [ "Offset of field: ip_frag_tbl_stat::fail_total", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).fail_nospace) as usize - ptr as usize }, - 40usize, + ][::std::mem::offset_of!(ip_frag_tbl_stat, fail_total) - 32usize]; + [ "Offset of field: ip_frag_tbl_stat::fail_nospace", - ); -} + ][::std::mem::offset_of!(ip_frag_tbl_stat, fail_nospace) - 40usize]; +}; impl Default for ip_frag_tbl_stat { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -352,6 +274,7 @@ impl Default for ip_frag_tbl_stat { /// fragmentation table #[repr(C)] #[repr(align(64))] +#[derive(Debug)] pub struct rte_ip_frag_tbl { ///< ttl for table entries. pub max_cycles: u64, @@ -371,82 +294,52 @@ pub struct rte_ip_frag_tbl { pub last: *mut ip_frag_pkt, ///< LRU list for table entries. pub lru: ip_pkt_list, - pub __bindgen_padding_0: u64, + pub __bindgen_padding_0: __BindgenOpaqueArray8<[u8; 8usize]>, ///< statistics counters. pub stat: ip_frag_tbl_stat, ///< hash table. pub pkt: __IncompleteArrayField, } -#[test] -fn bindgen_test_layout_rte_ip_frag_tbl() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 128usize, - "Size of rte_ip_frag_tbl", - ); - assert_eq!( - ::std::mem::align_of::(), - 64usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of rte_ip_frag_tbl"][::std::mem::size_of::() - 128usize]; + [ "Alignment of rte_ip_frag_tbl", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).max_cycles) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 64usize]; + [ "Offset of field: rte_ip_frag_tbl::max_cycles", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).entry_mask) as usize - ptr as usize }, - 8usize, + ][::std::mem::offset_of!(rte_ip_frag_tbl, max_cycles) - 0usize]; + [ "Offset of field: rte_ip_frag_tbl::entry_mask", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).max_entries) as usize - ptr as usize }, - 12usize, + ][::std::mem::offset_of!(rte_ip_frag_tbl, entry_mask) - 8usize]; + [ "Offset of field: rte_ip_frag_tbl::max_entries", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).use_entries) as usize - ptr as usize }, - 16usize, + ][::std::mem::offset_of!(rte_ip_frag_tbl, max_entries) - 12usize]; + [ "Offset of field: rte_ip_frag_tbl::use_entries", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).bucket_entries) as usize - ptr as usize }, - 20usize, + ][::std::mem::offset_of!(rte_ip_frag_tbl, use_entries) - 16usize]; + [ "Offset of field: rte_ip_frag_tbl::bucket_entries", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_entries) as usize - ptr as usize }, - 24usize, + ][::std::mem::offset_of!(rte_ip_frag_tbl, bucket_entries) - 20usize]; + [ "Offset of field: rte_ip_frag_tbl::nb_entries", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_buckets) as usize - ptr as usize }, - 28usize, + ][::std::mem::offset_of!(rte_ip_frag_tbl, nb_entries) - 24usize]; + [ "Offset of field: rte_ip_frag_tbl::nb_buckets", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).last) as usize - ptr as usize }, - 32usize, + ][::std::mem::offset_of!(rte_ip_frag_tbl, nb_buckets) - 28usize]; + [ "Offset of field: rte_ip_frag_tbl::last", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).lru) as usize - ptr as usize }, - 40usize, + ][::std::mem::offset_of!(rte_ip_frag_tbl, last) - 32usize]; + [ "Offset of field: rte_ip_frag_tbl::lru", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).stat) as usize - ptr as usize }, - 64usize, + ][::std::mem::offset_of!(rte_ip_frag_tbl, lru) - 40usize]; + [ "Offset of field: rte_ip_frag_tbl::stat", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pkt) as usize - ptr as usize }, - 128usize, + ][::std::mem::offset_of!(rte_ip_frag_tbl, stat) - 64usize]; + [ "Offset of field: rte_ip_frag_tbl::pkt", - ); -} + ][::std::mem::offset_of!(rte_ip_frag_tbl, pkt) - 128usize]; +}; impl Default for rte_ip_frag_tbl { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); diff --git a/bindgen-tests/tests/expectations/tests/layout_mbuf.rs b/bindgen-tests/tests/expectations/tests/layout_mbuf.rs index aa2c121c2d..ce6c58e39e 100644 --- a/bindgen-tests/tests/expectations/tests/layout_mbuf.rs +++ b/bindgen-tests/tests/expectations/tests/layout_mbuf.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,6 +126,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } pub const RTE_CACHE_LINE_MIN_SIZE: u32 = 64; pub const RTE_CACHE_LINE_SIZE: u32 = 64; @@ -197,10 +259,9 @@ pub union rte_mbuf__bindgen_ty_2 { pub __bindgen_anon_1: rte_mbuf__bindgen_ty_2__bindgen_ty_1, } #[repr(C)] -#[repr(align(4))] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct rte_mbuf__bindgen_ty_2__bindgen_ty_1 { - pub _bitfield_align_1: [u8; 0], + pub _bindgen_align: [u32; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -225,6 +286,31 @@ impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { } } #[inline] + pub unsafe fn l2_type_raw(this: *const Self) -> u32 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 4u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_l2_type_raw(this: *mut Self, val: u32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn l3_type(&self) -> u32 { unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u32) } } @@ -236,6 +322,31 @@ impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { } } #[inline] + pub unsafe fn l3_type_raw(this: *const Self) -> u32 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 4u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_l3_type_raw(this: *mut Self, val: u32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 4usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn l4_type(&self) -> u32 { unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 4u8) as u32) } } @@ -247,6 +358,31 @@ impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { } } #[inline] + pub unsafe fn l4_type_raw(this: *const Self) -> u32 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 8usize, 4u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_l4_type_raw(this: *mut Self, val: u32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 8usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn tun_type(&self) -> u32 { unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 4u8) as u32) } } @@ -258,6 +394,31 @@ impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { } } #[inline] + pub unsafe fn tun_type_raw(this: *const Self) -> u32 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 12usize, 4u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_tun_type_raw(this: *mut Self, val: u32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 12usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn inner_l2_type(&self) -> u32 { unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 4u8) as u32) } } @@ -269,6 +430,31 @@ impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { } } #[inline] + pub unsafe fn inner_l2_type_raw(this: *const Self) -> u32 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 16usize, 4u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_inner_l2_type_raw(this: *mut Self, val: u32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 16usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn inner_l3_type(&self) -> u32 { unsafe { ::std::mem::transmute(self._bitfield_1.get(20usize, 4u8) as u32) } } @@ -280,6 +466,31 @@ impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { } } #[inline] + pub unsafe fn inner_l3_type_raw(this: *const Self) -> u32 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 20usize, 4u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_inner_l3_type_raw(this: *mut Self, val: u32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 20usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn inner_l4_type(&self) -> u32 { unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 4u8) as u32) } } @@ -291,6 +502,31 @@ impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { } } #[inline] + pub unsafe fn inner_l4_type_raw(this: *const Self) -> u32 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 24usize, 4u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_inner_l4_type_raw(this: *mut Self, val: u32) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 24usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( l2_type: u32, l3_type: u32, @@ -583,11 +819,11 @@ pub union rte_mbuf__bindgen_ty_5 { pub __bindgen_anon_1: rte_mbuf__bindgen_ty_5__bindgen_ty_1, } #[repr(C)] -#[repr(align(8))] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct rte_mbuf__bindgen_ty_5__bindgen_ty_1 { - pub _bitfield_align_1: [u16; 0], + pub _bindgen_align: [u64; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 7usize]>, + pub __bindgen_padding_0: u8, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -611,6 +847,31 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { } } #[inline] + pub unsafe fn l2_len_raw(this: *const Self) -> u64 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 7u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_l2_len_raw(this: *mut Self, val: u64) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 7u8, + val as u64, + ) + } + } + #[inline] pub fn l3_len(&self) -> u64 { unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 9u8) as u64) } } @@ -622,6 +883,31 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { } } #[inline] + pub unsafe fn l3_len_raw(this: *const Self) -> u64 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 7usize, 9u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_l3_len_raw(this: *mut Self, val: u64) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 7usize, + 9u8, + val as u64, + ) + } + } + #[inline] pub fn l4_len(&self) -> u64 { unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u64) } } @@ -633,6 +919,31 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { } } #[inline] + pub unsafe fn l4_len_raw(this: *const Self) -> u64 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 16usize, 8u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_l4_len_raw(this: *mut Self, val: u64) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 16usize, + 8u8, + val as u64, + ) + } + } + #[inline] pub fn tso_segsz(&self) -> u64 { unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 16u8) as u64) } } @@ -644,6 +955,31 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { } } #[inline] + pub unsafe fn tso_segsz_raw(this: *const Self) -> u64 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 24usize, 16u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_tso_segsz_raw(this: *mut Self, val: u64) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 24usize, + 16u8, + val as u64, + ) + } + } + #[inline] pub fn outer_l3_len(&self) -> u64 { unsafe { ::std::mem::transmute(self._bitfield_1.get(40usize, 9u8) as u64) } } @@ -655,6 +991,31 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { } } #[inline] + pub unsafe fn outer_l3_len_raw(this: *const Self) -> u64 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 40usize, 9u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_outer_l3_len_raw(this: *mut Self, val: u64) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 40usize, + 9u8, + val as u64, + ) + } + } + #[inline] pub fn outer_l2_len(&self) -> u64 { unsafe { ::std::mem::transmute(self._bitfield_1.get(49usize, 7u8) as u64) } } @@ -666,6 +1027,31 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { } } #[inline] + pub unsafe fn outer_l2_len_raw(this: *const Self) -> u64 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 49usize, 7u8) + as u64, + ) + } + } + #[inline] + pub unsafe fn set_outer_l2_len_raw(this: *mut Self, val: u64) { + unsafe { + let val: u64 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 49usize, + 7u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( l2_len: u64, l3_len: u64, diff --git a/bindgen-tests/tests/expectations/tests/layout_mbuf_1_0.rs b/bindgen-tests/tests/expectations/tests/layout_mbuf_1_0.rs deleted file mode 100644 index 19394d271f..0000000000 --- a/bindgen-tests/tests/expectations/tests/layout_mbuf_1_0.rs +++ /dev/null @@ -1,1043 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct __BindgenBitfieldUnit { - storage: Storage, -} -impl __BindgenBitfieldUnit { - #[inline] - pub fn new(storage: Storage) -> Self { - Self { storage } - } -} -impl __BindgenBitfieldUnit -where - Storage: AsRef<[u8]> + AsMut<[u8]>, -{ - #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; - let bit_index = if cfg!(target_endian = "big") { - 7 - (index % 8) - } else { - index % 8 - }; - let mask = 1 << bit_index; - byte & mask == mask - } - #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; - let bit_index = if cfg!(target_endian = "big") { - 7 - (index % 8) - } else { - index % 8 - }; - let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } - } - #[inline] - pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { - debug_assert!(bit_width <= 64); - debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); - debug_assert!( - (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), - ); - let mut val = 0; - for i in 0..(bit_width as usize) { - if self.get_bit(i + bit_offset) { - let index = if cfg!(target_endian = "big") { - bit_width as usize - 1 - i - } else { - i - }; - val |= 1 << index; - } - } - val - } - #[inline] - pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { - debug_assert!(bit_width <= 64); - debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); - debug_assert!( - (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), - ); - for i in 0..(bit_width as usize) { - let mask = 1 << i; - let val_bit_is_set = val & mask == mask; - let index = if cfg!(target_endian = "big") { - bit_width as usize - 1 - i - } else { - i - }; - self.set_bit(index + bit_offset, val_bit_is_set); - } - } -} -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -pub const RTE_CACHE_LINE_MIN_SIZE: u32 = 64; -pub const RTE_CACHE_LINE_SIZE: u32 = 64; -pub type phys_addr_t = u64; -pub type MARKER = [*mut ::std::os::raw::c_void; 0usize]; -pub type MARKER8 = [u8; 0usize]; -pub type MARKER64 = [u64; 0usize]; -/// The atomic counter structure. -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_atomic16_t { - ///< An internal counter value. - pub cnt: i16, -} -#[test] -fn bindgen_test_layout_rte_atomic16_t() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 2usize, - "Size of rte_atomic16_t", - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of rte_atomic16_t", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).cnt) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_atomic16_t::cnt", - ); -} -impl Clone for rte_atomic16_t { - fn clone(&self) -> Self { - *self - } -} -/// The generic rte_mbuf, containing a packet mbuf. -#[repr(C)] -pub struct rte_mbuf { - pub cacheline0: MARKER, - ///< Virtual address of segment buffer. - pub buf_addr: *mut ::std::os::raw::c_void, - ///< Physical address of segment buffer. - pub buf_physaddr: phys_addr_t, - ///< Length of segment buffer. - pub buf_len: u16, - pub rearm_data: MARKER8, - pub data_off: u16, - pub __bindgen_anon_1: rte_mbuf__bindgen_ty_1, - ///< Number of segments. - pub nb_segs: u8, - ///< Input port. - pub port: u8, - ///< Offload features. - pub ol_flags: u64, - pub rx_descriptor_fields1: MARKER, - pub __bindgen_anon_2: rte_mbuf__bindgen_ty_2, - ///< Total pkt len: sum of all segments. - pub pkt_len: u32, - ///< Amount of data in segment buffer. - pub data_len: u16, - /// VLAN TCI (CPU order), valid if PKT_RX_VLAN_STRIPPED is set. - pub vlan_tci: u16, - ///< hash information - pub hash: rte_mbuf__bindgen_ty_3, - ///< Sequence number. See also rte_reorder_insert() - pub seqn: u32, - /// Outer VLAN TCI (CPU order), valid if PKT_RX_QINQ_STRIPPED is set. - pub vlan_tci_outer: u16, - pub cacheline1: MARKER, - pub __bindgen_anon_3: rte_mbuf__bindgen_ty_4, - ///< Pool from which mbuf was allocated. - pub pool: *mut rte_mempool, - ///< Next segment of scattered packet. - pub next: *mut rte_mbuf, - pub __bindgen_anon_4: rte_mbuf__bindgen_ty_5, - /** Size of the application private data. In case of an indirect - mbuf, it stores the direct mbuf private data size.*/ - pub priv_size: u16, - /// Timesync flags for use with IEEE1588. - pub timesync: u16, - pub __bindgen_padding_0: [u32; 7usize], -} -/** 16-bit Reference counter. - It should only be accessed using the following functions: - rte_mbuf_refcnt_update(), rte_mbuf_refcnt_read(), and - rte_mbuf_refcnt_set(). The functionality of these functions (atomic, - or non-atomic) is controlled by the CONFIG_RTE_MBUF_REFCNT_ATOMIC - config option.*/ -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_mbuf__bindgen_ty_1 { - ///< Atomically accessed refcnt - pub refcnt_atomic: __BindgenUnionField, - ///< Non-atomically accessed refcnt - pub refcnt: __BindgenUnionField, - pub bindgen_union_field: u16, -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 2usize, - "Size of rte_mbuf__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of rte_mbuf__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).refcnt_atomic) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_1::refcnt_atomic", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).refcnt) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_1::refcnt", - ); -} -impl Clone for rte_mbuf__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_mbuf__bindgen_ty_2 { - ///< L2/L3/L4 and tunnel information. - pub packet_type: __BindgenUnionField, - pub __bindgen_anon_1: __BindgenUnionField, - pub bindgen_union_field: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_mbuf__bindgen_ty_2__bindgen_ty_1 { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, - pub __bindgen_align: [u32; 0usize], -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_2__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of rte_mbuf__bindgen_ty_2__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_mbuf__bindgen_ty_2__bindgen_ty_1", - ); -} -impl Clone for rte_mbuf__bindgen_ty_2__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -impl rte_mbuf__bindgen_ty_2__bindgen_ty_1 { - #[inline] - pub fn l2_type(&self) -> u32 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u32) } - } - #[inline] - pub fn set_l2_type(&mut self, val: u32) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 4u8, val as u64) - } - } - #[inline] - pub fn l3_type(&self) -> u32 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u32) } - } - #[inline] - pub fn set_l3_type(&mut self, val: u32) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(4usize, 4u8, val as u64) - } - } - #[inline] - pub fn l4_type(&self) -> u32 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 4u8) as u32) } - } - #[inline] - pub fn set_l4_type(&mut self, val: u32) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(8usize, 4u8, val as u64) - } - } - #[inline] - pub fn tun_type(&self) -> u32 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(12usize, 4u8) as u32) } - } - #[inline] - pub fn set_tun_type(&mut self, val: u32) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(12usize, 4u8, val as u64) - } - } - #[inline] - pub fn inner_l2_type(&self) -> u32 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 4u8) as u32) } - } - #[inline] - pub fn set_inner_l2_type(&mut self, val: u32) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(16usize, 4u8, val as u64) - } - } - #[inline] - pub fn inner_l3_type(&self) -> u32 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(20usize, 4u8) as u32) } - } - #[inline] - pub fn set_inner_l3_type(&mut self, val: u32) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(20usize, 4u8, val as u64) - } - } - #[inline] - pub fn inner_l4_type(&self) -> u32 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 4u8) as u32) } - } - #[inline] - pub fn set_inner_l4_type(&mut self, val: u32) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(24usize, 4u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - l2_type: u32, - l3_type: u32, - l4_type: u32, - tun_type: u32, - inner_l2_type: u32, - inner_l3_type: u32, - inner_l4_type: u32, - ) -> __BindgenBitfieldUnit<[u8; 4usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); - __bindgen_bitfield_unit - .set( - 0usize, - 4u8, - { - let l2_type: u32 = unsafe { ::std::mem::transmute(l2_type) }; - l2_type as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 4usize, - 4u8, - { - let l3_type: u32 = unsafe { ::std::mem::transmute(l3_type) }; - l3_type as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 8usize, - 4u8, - { - let l4_type: u32 = unsafe { ::std::mem::transmute(l4_type) }; - l4_type as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 12usize, - 4u8, - { - let tun_type: u32 = unsafe { ::std::mem::transmute(tun_type) }; - tun_type as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 16usize, - 4u8, - { - let inner_l2_type: u32 = unsafe { - ::std::mem::transmute(inner_l2_type) - }; - inner_l2_type as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 20usize, - 4u8, - { - let inner_l3_type: u32 = unsafe { - ::std::mem::transmute(inner_l3_type) - }; - inner_l3_type as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 24usize, - 4u8, - { - let inner_l4_type: u32 = unsafe { - ::std::mem::transmute(inner_l4_type) - }; - inner_l4_type as u64 - }, - ); - __bindgen_bitfield_unit - } -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of rte_mbuf__bindgen_ty_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_mbuf__bindgen_ty_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).packet_type) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_2::packet_type", - ); -} -impl Clone for rte_mbuf__bindgen_ty_2 { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_mbuf__bindgen_ty_3 { - ///< RSS hash result if RSS enabled - pub rss: __BindgenUnionField, - ///< Filter identifier if FDIR enabled - pub fdir: __BindgenUnionField, - ///< Hierarchical scheduler - pub sched: __BindgenUnionField, - ///< User defined tags. See rte_distributor_process() - pub usr: __BindgenUnionField, - pub bindgen_union_field: [u32; 2usize], -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_mbuf__bindgen_ty_3__bindgen_ty_1 { - pub __bindgen_anon_1: rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1, - pub hi: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1 { - pub __bindgen_anon_1: __BindgenUnionField< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, - >, - pub lo: __BindgenUnionField, - pub bindgen_union_field: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 { - pub hash: u16, - pub id: u16, -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, - > = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, - >(), - 4usize, - "Size of rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, - >(), - 2usize, - "Alignment of rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).hash) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1::hash", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize }, - 2usize, - "Offset of field: rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1::id", - ); -} -impl Clone for rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit< - rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1, - > = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).lo) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1::lo", - ); -} -impl Clone for rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_3__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of rte_mbuf__bindgen_ty_3__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_mbuf__bindgen_ty_3__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).hi) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_mbuf__bindgen_ty_3__bindgen_ty_1::hi", - ); -} -impl Clone for rte_mbuf__bindgen_ty_3__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_mbuf__bindgen_ty_3__bindgen_ty_2 { - pub lo: u32, - pub hi: u32, -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_3__bindgen_ty_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of rte_mbuf__bindgen_ty_3__bindgen_ty_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_mbuf__bindgen_ty_3__bindgen_ty_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).lo) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_3__bindgen_ty_2::lo", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).hi) as usize - ptr as usize }, - 4usize, - "Offset of field: rte_mbuf__bindgen_ty_3__bindgen_ty_2::hi", - ); -} -impl Clone for rte_mbuf__bindgen_ty_3__bindgen_ty_2 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_3() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of rte_mbuf__bindgen_ty_3", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of rte_mbuf__bindgen_ty_3", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rss) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_3::rss", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).fdir) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_3::fdir", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).sched) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_3::sched", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).usr) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_3::usr", - ); -} -impl Clone for rte_mbuf__bindgen_ty_3 { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_mbuf__bindgen_ty_4 { - ///< Can be used for external metadata - pub userdata: __BindgenUnionField<*mut ::std::os::raw::c_void>, - ///< Allow 8-byte userdata on 32-bit - pub udata64: __BindgenUnionField, - pub bindgen_union_field: u64, -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_4() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of rte_mbuf__bindgen_ty_4", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of rte_mbuf__bindgen_ty_4", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).userdata) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_4::userdata", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).udata64) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_4::udata64", - ); -} -impl Clone for rte_mbuf__bindgen_ty_4 { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_mbuf__bindgen_ty_5 { - ///< combined for easy fetch - pub tx_offload: __BindgenUnionField, - pub __bindgen_anon_1: __BindgenUnionField, - pub bindgen_union_field: u64, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_mbuf__bindgen_ty_5__bindgen_ty_1 { - pub _bitfield_align_1: [u16; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 7usize]>, - pub __bindgen_align: [u64; 0usize], -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_5__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of rte_mbuf__bindgen_ty_5__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of rte_mbuf__bindgen_ty_5__bindgen_ty_1", - ); -} -impl Clone for rte_mbuf__bindgen_ty_5__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { - #[inline] - pub fn l2_len(&self) -> u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 7u8) as u64) } - } - #[inline] - pub fn set_l2_len(&mut self, val: u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 7u8, val as u64) - } - } - #[inline] - pub fn l3_len(&self) -> u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 9u8) as u64) } - } - #[inline] - pub fn set_l3_len(&mut self, val: u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(7usize, 9u8, val as u64) - } - } - #[inline] - pub fn l4_len(&self) -> u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 8u8) as u64) } - } - #[inline] - pub fn set_l4_len(&mut self, val: u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(16usize, 8u8, val as u64) - } - } - #[inline] - pub fn tso_segsz(&self) -> u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(24usize, 16u8) as u64) } - } - #[inline] - pub fn set_tso_segsz(&mut self, val: u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(24usize, 16u8, val as u64) - } - } - #[inline] - pub fn outer_l3_len(&self) -> u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(40usize, 9u8) as u64) } - } - #[inline] - pub fn set_outer_l3_len(&mut self, val: u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(40usize, 9u8, val as u64) - } - } - #[inline] - pub fn outer_l2_len(&self) -> u64 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(49usize, 7u8) as u64) } - } - #[inline] - pub fn set_outer_l2_len(&mut self, val: u64) { - unsafe { - let val: u64 = ::std::mem::transmute(val); - self._bitfield_1.set(49usize, 7u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - l2_len: u64, - l3_len: u64, - l4_len: u64, - tso_segsz: u64, - outer_l3_len: u64, - outer_l2_len: u64, - ) -> __BindgenBitfieldUnit<[u8; 7usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 7usize]> = Default::default(); - __bindgen_bitfield_unit - .set( - 0usize, - 7u8, - { - let l2_len: u64 = unsafe { ::std::mem::transmute(l2_len) }; - l2_len as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 7usize, - 9u8, - { - let l3_len: u64 = unsafe { ::std::mem::transmute(l3_len) }; - l3_len as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 16usize, - 8u8, - { - let l4_len: u64 = unsafe { ::std::mem::transmute(l4_len) }; - l4_len as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 24usize, - 16u8, - { - let tso_segsz: u64 = unsafe { ::std::mem::transmute(tso_segsz) }; - tso_segsz as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 40usize, - 9u8, - { - let outer_l3_len: u64 = unsafe { - ::std::mem::transmute(outer_l3_len) - }; - outer_l3_len as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 49usize, - 7u8, - { - let outer_l2_len: u64 = unsafe { - ::std::mem::transmute(outer_l2_len) - }; - outer_l2_len as u64 - }, - ); - __bindgen_bitfield_unit - } -} -#[test] -fn bindgen_test_layout_rte_mbuf__bindgen_ty_5() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of rte_mbuf__bindgen_ty_5", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of rte_mbuf__bindgen_ty_5", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).tx_offload) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf__bindgen_ty_5::tx_offload", - ); -} -impl Clone for rte_mbuf__bindgen_ty_5 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_rte_mbuf() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 128usize, "Size of rte_mbuf"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).cacheline0) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf::cacheline0", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).buf_addr) as usize - ptr as usize }, - 0usize, - "Offset of field: rte_mbuf::buf_addr", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).buf_physaddr) as usize - ptr as usize }, - 8usize, - "Offset of field: rte_mbuf::buf_physaddr", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).buf_len) as usize - ptr as usize }, - 16usize, - "Offset of field: rte_mbuf::buf_len", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rearm_data) as usize - ptr as usize }, - 18usize, - "Offset of field: rte_mbuf::rearm_data", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).data_off) as usize - ptr as usize }, - 18usize, - "Offset of field: rte_mbuf::data_off", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).nb_segs) as usize - ptr as usize }, - 22usize, - "Offset of field: rte_mbuf::nb_segs", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).port) as usize - ptr as usize }, - 23usize, - "Offset of field: rte_mbuf::port", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ol_flags) as usize - ptr as usize }, - 24usize, - "Offset of field: rte_mbuf::ol_flags", - ); - assert_eq!( - unsafe { - ::std::ptr::addr_of!((*ptr).rx_descriptor_fields1) as usize - ptr as usize - }, - 32usize, - "Offset of field: rte_mbuf::rx_descriptor_fields1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pkt_len) as usize - ptr as usize }, - 36usize, - "Offset of field: rte_mbuf::pkt_len", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).data_len) as usize - ptr as usize }, - 40usize, - "Offset of field: rte_mbuf::data_len", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vlan_tci) as usize - ptr as usize }, - 42usize, - "Offset of field: rte_mbuf::vlan_tci", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).hash) as usize - ptr as usize }, - 44usize, - "Offset of field: rte_mbuf::hash", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).seqn) as usize - ptr as usize }, - 52usize, - "Offset of field: rte_mbuf::seqn", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).vlan_tci_outer) as usize - ptr as usize }, - 56usize, - "Offset of field: rte_mbuf::vlan_tci_outer", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).cacheline1) as usize - ptr as usize }, - 64usize, - "Offset of field: rte_mbuf::cacheline1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).pool) as usize - ptr as usize }, - 72usize, - "Offset of field: rte_mbuf::pool", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).next) as usize - ptr as usize }, - 80usize, - "Offset of field: rte_mbuf::next", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).priv_size) as usize - ptr as usize }, - 96usize, - "Offset of field: rte_mbuf::priv_size", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).timesync) as usize - ptr as usize }, - 98usize, - "Offset of field: rte_mbuf::timesync", - ); -} -impl Default for rte_mbuf { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -///< Pool from which mbuf was allocated. -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct rte_mempool { - pub _address: u8, -} -impl Clone for rte_mempool { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/libclang-9/atomic-constant.rs b/bindgen-tests/tests/expectations/tests/libclang-9/atomic-constant.rs index ce12eaad3a..098beb43de 100644 --- a/bindgen-tests/tests/expectations/tests/libclang-9/atomic-constant.rs +++ b/bindgen-tests/tests/expectations/tests/libclang-9/atomic-constant.rs @@ -1,4 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub static mut b: ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/libclang-9/issue-544-stylo-creduce-2.rs b/bindgen-tests/tests/expectations/tests/libclang-9/issue-544-stylo-creduce-2.rs index 5c5ad156e3..d64a8948ee 100644 --- a/bindgen-tests/tests/expectations/tests/libclang-9/issue-544-stylo-creduce-2.rs +++ b/bindgen-tests/tests/expectations/tests/libclang-9/issue-544-stylo-creduce-2.rs @@ -1,11 +1,19 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C)] +pub struct __BindgenOpaqueArray(pub T); +impl Default for __BindgenOpaqueArray<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Foo { - pub member: *mut [u8; 0usize], + pub member: *mut __BindgenOpaqueArray<[u8; 0usize]>, } -pub type Foo_FirstAlias = [u8; 0usize]; -pub type Foo_SecondAlias = [u8; 0usize]; +pub type Foo_FirstAlias = __BindgenOpaqueArray<[u8; 0usize]>; +pub type Foo_SecondAlias = __BindgenOpaqueArray<[u8; 0usize]>; impl Default for Foo { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); diff --git a/bindgen-tests/tests/expectations/tests/long_double.rs b/bindgen-tests/tests/expectations/tests/long_double.rs index aa3109ca43..4a8b13e9b0 100644 --- a/bindgen-tests/tests/expectations/tests/long_double.rs +++ b/bindgen-tests/tests/expectations/tests/long_double.rs @@ -5,15 +5,9 @@ pub struct foo { pub bar: u128, } -#[test] -fn bindgen_test_layout_foo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 16usize, "Size of foo"); - assert_eq!(::std::mem::align_of::(), 16usize, "Alignment of foo"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).bar) as usize - ptr as usize }, - 0usize, - "Offset of field: foo::bar", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of foo"][::std::mem::size_of::() - 16usize]; + ["Alignment of foo"][::std::mem::align_of::() - 16usize]; + ["Offset of field: foo::bar"][::std::mem::offset_of!(foo, bar) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/macro-expr-uncommon-token.rs b/bindgen-tests/tests/expectations/tests/macro-expr-uncommon-token.rs index c905e5aa90..785ef4bb9f 100644 --- a/bindgen-tests/tests/expectations/tests/macro-expr-uncommon-token.rs +++ b/bindgen-tests/tests/expectations/tests/macro-expr-uncommon-token.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub const MODBUS_WOOT: u32 = 3; -extern "C" { +unsafe extern "C" { pub fn foo(); } diff --git a/bindgen-tests/tests/expectations/tests/macro_const_1_0.rs b/bindgen-tests/tests/expectations/tests/macro_const_1_0.rs deleted file mode 100644 index 2f3e228d80..0000000000 --- a/bindgen-tests/tests/expectations/tests/macro_const_1_0.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -pub const foo: &'static [u8; 4] = b"bar\0"; -pub const CHAR: u8 = 98u8; -pub const CHARR: u8 = 0u8; -pub const FLOAT: f64 = 5.09; -pub const FLOAT_EXPR: f64 = 0.005; -pub const LONG: u32 = 3; -pub const INVALID_UTF8: &'static [u8; 5] = b"\xF0(\x8C(\0"; diff --git a/bindgen-tests/tests/expectations/tests/mangling-ios.rs b/bindgen-tests/tests/expectations/tests/mangling-ios.rs index 05b7aecd3e..736d379f01 100644 --- a/bindgen-tests/tests/expectations/tests/mangling-ios.rs +++ b/bindgen-tests/tests/expectations/tests/mangling-ios.rs @@ -1,4 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn foo(); } diff --git a/bindgen-tests/tests/expectations/tests/mangling-linux32.rs b/bindgen-tests/tests/expectations/tests/mangling-linux32.rs index ab1f799694..b6ed9146da 100644 --- a/bindgen-tests/tests/expectations/tests/mangling-linux32.rs +++ b/bindgen-tests/tests/expectations/tests/mangling-linux32.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn foo(); } #[repr(C)] @@ -7,7 +7,7 @@ extern "C" { pub struct Foo { pub _address: u8, } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo4sBarE"] pub static mut Foo_sBar: bool; } diff --git a/bindgen-tests/tests/expectations/tests/mangling-linux64.rs b/bindgen-tests/tests/expectations/tests/mangling-linux64.rs index ab1f799694..b6ed9146da 100644 --- a/bindgen-tests/tests/expectations/tests/mangling-linux64.rs +++ b/bindgen-tests/tests/expectations/tests/mangling-linux64.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn foo(); } #[repr(C)] @@ -7,7 +7,7 @@ extern "C" { pub struct Foo { pub _address: u8, } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo4sBarE"] pub static mut Foo_sBar: bool; } diff --git a/bindgen-tests/tests/expectations/tests/mangling-macos.rs b/bindgen-tests/tests/expectations/tests/mangling-macos.rs index b5d78cedb5..237859e23b 100644 --- a/bindgen-tests/tests/expectations/tests/mangling-macos.rs +++ b/bindgen-tests/tests/expectations/tests/mangling-macos.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn foo(); } #[repr(C)] @@ -7,7 +7,7 @@ extern "C" { pub struct Foo { pub _address: u8, } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}__ZN3Foo4sBarE"] pub static mut Foo_sBar: bool; } diff --git a/bindgen-tests/tests/expectations/tests/mangling-win32.rs b/bindgen-tests/tests/expectations/tests/mangling-win32.rs index 572b69962c..263f619374 100644 --- a/bindgen-tests/tests/expectations/tests/mangling-win32.rs +++ b/bindgen-tests/tests/expectations/tests/mangling-win32.rs @@ -1,5 +1,6 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +#![cfg(target = "i686-pc-windows-msvc")] +unsafe extern "C" { pub fn foo(); } #[repr(C)] @@ -7,7 +8,7 @@ extern "C" { pub struct Foo { pub _address: u8, } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}?sBar@Foo@@2_NA"] pub static mut Foo_sBar: bool; } @@ -16,20 +17,20 @@ const _: () = { ["Size of Foo"][::std::mem::size_of::() - 1usize]; ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; }; -extern "fastcall" { +unsafe extern "fastcall" { pub fn fast_call_func_no_args() -> ::std::os::raw::c_int; } -extern "fastcall" { +unsafe extern "fastcall" { pub fn fast_call_func_many_args( arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int, arg3: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } -extern "stdcall" { +unsafe extern "stdcall" { pub fn std_call_func_no_args() -> ::std::os::raw::c_int; } -extern "stdcall" { +unsafe extern "stdcall" { pub fn std_call_func_many_args( arg1: ::std::os::raw::c_int, arg2: ::std::os::raw::c_int, diff --git a/bindgen-tests/tests/expectations/tests/mangling-win64.rs b/bindgen-tests/tests/expectations/tests/mangling-win64.rs index 1e71710f6c..2a782480ed 100644 --- a/bindgen-tests/tests/expectations/tests/mangling-win64.rs +++ b/bindgen-tests/tests/expectations/tests/mangling-win64.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn foo(); } #[repr(C)] @@ -7,7 +7,7 @@ extern "C" { pub struct Foo { pub _address: u8, } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}?sBar@Foo@@2_NA"] pub static mut Foo_sBar: bool; } diff --git a/bindgen-tests/tests/expectations/tests/merge_extern_blocks_post_1_82.rs b/bindgen-tests/tests/expectations/tests/merge_extern_blocks_post_1_82.rs new file mode 100644 index 0000000000..98659f6382 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/merge_extern_blocks_post_1_82.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub mod root { + #[allow(unused_imports)] + use self::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Point { + pub x: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Point"][::std::mem::size_of::() - 4usize]; + ["Alignment of Point"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Point::x"][::std::mem::offset_of!(Point, x) - 0usize]; + }; + pub mod ns { + #[allow(unused_imports)] + use self::super::super::root; + #[repr(C)] + #[derive(Debug, Default, Copy, Clone)] + pub struct Point { + pub x: ::std::os::raw::c_int, + } + #[allow(clippy::unnecessary_operation, clippy::identity_op)] + const _: () = { + ["Size of Point"][::std::mem::size_of::() - 4usize]; + ["Alignment of Point"][::std::mem::align_of::() - 4usize]; + ["Offset of field: Point::x"][::std::mem::offset_of!(Point, x) - 0usize]; + }; + unsafe extern "C" { + #[link_name = "\u{1}_ZN2ns3fooEv"] + pub fn foo() -> ::std::os::raw::c_int; + #[link_name = "\u{1}_ZN2ns3barEv"] + pub fn bar() -> ::std::os::raw::c_int; + } + } + unsafe extern "C" { + #[link_name = "\u{1}_Z3foov"] + pub fn foo() -> ::std::os::raw::c_int; + #[link_name = "\u{1}_Z3barv"] + pub fn bar() -> ::std::os::raw::c_int; + } +} diff --git a/bindgen-tests/tests/expectations/tests/merge-extern-blocks.rs b/bindgen-tests/tests/expectations/tests/merge_extern_blocks_pre_1_82.rs similarity index 100% rename from bindgen-tests/tests/expectations/tests/merge-extern-blocks.rs rename to bindgen-tests/tests/expectations/tests/merge_extern_blocks_pre_1_82.rs diff --git a/bindgen-tests/tests/expectations/tests/method-mangling.rs b/bindgen-tests/tests/expectations/tests/method-mangling.rs index bde0a0f2ff..4c86825cce 100644 --- a/bindgen-tests/tests/expectations/tests/method-mangling.rs +++ b/bindgen-tests/tests/expectations/tests/method-mangling.rs @@ -9,7 +9,7 @@ const _: () = { ["Size of Foo"][::std::mem::size_of::() - 1usize]; ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Foo4typeEv"] pub fn Foo_type(this: *mut Foo) -> ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/namespace.rs b/bindgen-tests/tests/expectations/tests/namespace.rs index f4f2a76c3e..4e58fa7ab1 100644 --- a/bindgen-tests/tests/expectations/tests/namespace.rs +++ b/bindgen-tests/tests/expectations/tests/namespace.rs @@ -3,7 +3,7 @@ pub mod root { #[allow(unused_imports)] use self::super::root; - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_Z9top_levelv"] pub fn top_level(); } @@ -12,7 +12,7 @@ pub mod root { use self::super::super::root; pub type whatever_other_thing_t = whatever_int_t; pub type whatever_int_t = ::std::os::raw::c_int; - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN8whatever11in_whateverEv"] pub fn in_whatever(); } @@ -69,15 +69,15 @@ pub mod root { } } } - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN1w3hehEv"] pub fn heh() -> root::w::whatever_int_t; } - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN1w3fooEv"] pub fn foo() -> root::C<::std::os::raw::c_int>; } - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN1w4barrEv"] pub fn barr() -> root::C; } @@ -85,7 +85,7 @@ pub mod root { pub mod foobar { #[allow(unused_imports)] use self::super::super::root; - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN6foobar3fooEv"] pub fn foo(); } @@ -93,7 +93,7 @@ pub mod root { pub mod faraway { #[allow(unused_imports)] use self::super::super::root; - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN7faraway3barEv"] pub fn bar(); } diff --git a/bindgen-tests/tests/expectations/tests/nested-class-field.rs b/bindgen-tests/tests/expectations/tests/nested-class-field.rs new file mode 100644 index 0000000000..91500f4142 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/nested-class-field.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct A { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::() - 1usize]; + ["Alignment of A"][::std::mem::align_of::() - 1usize]; +}; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct A_I { + pub i: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A_I"][::std::mem::size_of::() - 4usize]; + ["Alignment of A_I"][::std::mem::align_of::() - 4usize]; + ["Offset of field: A_I::i"][::std::mem::offset_of!(A_I, i) - 0usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/nested_vtable.rs b/bindgen-tests/tests/expectations/tests/nested_vtable.rs index 6356f9efd1..12aa2ea441 100644 --- a/bindgen-tests/tests/expectations/tests/nested_vtable.rs +++ b/bindgen-tests/tests/expectations/tests/nested_vtable.rs @@ -24,7 +24,7 @@ impl Default for nsISupports { } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN11nsISupports14QueryInterfaceEv"] pub fn nsISupports_QueryInterface( this: *mut ::std::os::raw::c_void, diff --git a/bindgen-tests/tests/expectations/tests/new-type-alias.rs b/bindgen-tests/tests/expectations/tests/new-type-alias.rs new file mode 100644 index 0000000000..f63069cbe2 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/new-type-alias.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const true_: u32 = 1; +#[repr(transparent)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo(pub u64); +pub const Foo_A: Foo = Foo(1); +#[repr(transparent)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bar(pub ::std::os::raw::c_char); +pub const Bar_A: Bar = Bar(97); +#[repr(transparent)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Baz(pub f32); +pub const Baz_A: Baz = Baz(3.25); +#[repr(transparent)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bang(pub bool); +pub const Bang_A: Bang = Bang(true); +pub type Boom = u64; +pub const Boom_A: Boom = 2; diff --git a/bindgen-tests/tests/expectations/tests/newtype-enum.rs b/bindgen-tests/tests/expectations/tests/newtype-enum.rs index ea25950de0..0045c52a61 100644 --- a/bindgen-tests/tests/expectations/tests/newtype-enum.rs +++ b/bindgen-tests/tests/expectations/tests/newtype-enum.rs @@ -1,14 +1,8 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] impl Foo { pub const Bar: Foo = Foo(2); -} -impl Foo { pub const Baz: Foo = Foo(4); -} -impl Foo { pub const Duplicated: Foo = Foo(4); -} -impl Foo { pub const Negative: Foo = Foo(-3); } #[repr(transparent)] diff --git a/bindgen-tests/tests/expectations/tests/no_debug_bypass_impl_debug.rs b/bindgen-tests/tests/expectations/tests/no_debug_bypass_impl_debug.rs index d972c74376..ceec3823ae 100644 --- a/bindgen-tests/tests/expectations/tests/no_debug_bypass_impl_debug.rs +++ b/bindgen-tests/tests/expectations/tests/no_debug_bypass_impl_debug.rs @@ -1,5 +1,6 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] +#[derive(Debug)] pub struct Generic { pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub t: [T; 40usize], @@ -13,11 +14,6 @@ impl Default for Generic { } } } -impl ::std::fmt::Debug for Generic { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(f, "Generic {{ t: Array with length 40 }}") - } -} #[repr(C)] pub struct NoDebug { pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, diff --git a/bindgen-tests/tests/expectations/tests/no_default_bypass_derive_default.rs b/bindgen-tests/tests/expectations/tests/no_default_bypass_derive_default.rs index 58f3684ac9..3dfd34474a 100644 --- a/bindgen-tests/tests/expectations/tests/no_default_bypass_derive_default.rs +++ b/bindgen-tests/tests/expectations/tests/no_default_bypass_derive_default.rs @@ -1,5 +1,6 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] +#[derive(Debug)] pub struct Generic { pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub t: [T; 40usize], @@ -14,6 +15,7 @@ impl Default for Generic { } } #[repr(C)] +#[derive(Debug)] pub struct NoDefault { pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub t: [T; 40usize], diff --git a/bindgen-tests/tests/expectations/tests/non-type-params.rs b/bindgen-tests/tests/expectations/tests/non-type-params.rs index 64b293cb1b..325620b9bb 100644 --- a/bindgen-tests/tests/expectations/tests/non-type-params.rs +++ b/bindgen-tests/tests/expectations/tests/non-type-params.rs @@ -1,11 +1,19 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C)] +pub struct __BindgenOpaqueArray(pub T); +impl Default for __BindgenOpaqueArray<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} pub type Array16 = u8; -pub type ArrayInt4 = [u32; 4usize]; +pub type ArrayInt4 = __BindgenOpaqueArray<[u32; 4usize]>; #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct UsesArray { - pub array_char_16: [u8; 16usize], - pub array_bool_8: [u8; 8usize], + pub array_char_16: __BindgenOpaqueArray<[u8; 16usize]>, + pub array_bool_8: __BindgenOpaqueArray<[u8; 8usize]>, pub array_int_4: ArrayInt4, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] diff --git a/bindgen-tests/tests/expectations/tests/noreturn.rs b/bindgen-tests/tests/expectations/tests/noreturn.rs index 2081d3d44b..0e601b5510 100644 --- a/bindgen-tests/tests/expectations/tests/noreturn.rs +++ b/bindgen-tests/tests/expectations/tests/noreturn.rs @@ -1,21 +1,21 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z1fv"] pub fn f() -> !; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z1gv"] pub fn g() -> !; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z1hv"] pub fn h() -> !; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z1iPFvvE"] pub fn i(arg: ::std::option::Option !>); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z1jPFvvE"] pub fn j(arg: ::std::option::Option !>) -> !; } diff --git a/bindgen-tests/tests/expectations/tests/nsBaseHashtable.rs b/bindgen-tests/tests/expectations/tests/nsBaseHashtable.rs index f2f7eefb46..81b9f000c6 100644 --- a/bindgen-tests/tests/expectations/tests/nsBaseHashtable.rs +++ b/bindgen-tests/tests/expectations/tests/nsBaseHashtable.rs @@ -1,4 +1,12 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C)] +pub struct __BindgenOpaqueArray(pub T); +impl Default for __BindgenOpaqueArray<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct nsBaseHashtableET { @@ -14,7 +22,7 @@ pub struct nsTHashtable { pub struct nsBaseHashtable { pub _address: u8, } -pub type nsBaseHashtable_KeyType = [u8; 0usize]; +pub type nsBaseHashtable_KeyType = __BindgenOpaqueArray<[u8; 0usize]>; pub type nsBaseHashtable_EntryType = nsBaseHashtableET; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/bindgen-tests/tests/expectations/tests/objc_class.rs b/bindgen-tests/tests/expectations/tests/objc_class.rs index 50bdea53ee..a7346d1ee9 100644 --- a/bindgen-tests/tests/expectations/tests/objc_class.rs +++ b/bindgen-tests/tests/expectations/tests/objc_class.rs @@ -3,7 +3,7 @@ use objc::{self, msg_send, sel, sel_impl, class}; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; -extern "C" { +unsafe extern "C" { pub static mut fooVar: Foo; } #[repr(transparent)] diff --git a/bindgen-tests/tests/expectations/tests/objc_interface_type.rs b/bindgen-tests/tests/expectations/tests/objc_interface_type.rs index 66c65be2d7..56ad75ed25 100644 --- a/bindgen-tests/tests/expectations/tests/objc_interface_type.rs +++ b/bindgen-tests/tests/expectations/tests/objc_interface_type.rs @@ -40,9 +40,9 @@ impl Default for FooStruct { } } } -extern "C" { +unsafe extern "C" { pub fn fooFunc(foo: Foo); } -extern "C" { +unsafe extern "C" { pub static mut kFoo: Foo; } diff --git a/bindgen-tests/tests/expectations/tests/objc_sel_and_id.rs b/bindgen-tests/tests/expectations/tests/objc_sel_and_id.rs index 25854d8488..cf38af4e64 100644 --- a/bindgen-tests/tests/expectations/tests/objc_sel_and_id.rs +++ b/bindgen-tests/tests/expectations/tests/objc_sel_and_id.rs @@ -3,12 +3,12 @@ use objc::{self, msg_send, sel, sel_impl, class}; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; -extern "C" { +unsafe extern "C" { pub static mut object: id; } -extern "C" { +unsafe extern "C" { pub static mut selector: objc::runtime::Sel; } -extern "C" { +unsafe extern "C" { pub fn f(object: id, selector: objc::runtime::Sel); } diff --git a/bindgen-tests/tests/expectations/tests/objc_template.rs b/bindgen-tests/tests/expectations/tests/objc_template.rs index ee47f67d4c..1c70009df3 100644 --- a/bindgen-tests/tests/expectations/tests/objc_template.rs +++ b/bindgen-tests/tests/expectations/tests/objc_template.rs @@ -3,6 +3,14 @@ use objc::{self, msg_send, sel, sel_impl, class}; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C, align(8))] +pub struct __BindgenOpaqueArray8(pub T); +impl Default for __BindgenOpaqueArray8<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} #[repr(transparent)] #[derive(Debug, Copy, Clone)] pub struct Foo(pub id); @@ -20,7 +28,7 @@ impl Foo { } impl IFoo for Foo {} pub trait IFoo: Sized + std::ops::Deref { - unsafe fn get(&self) -> u64 + unsafe fn get(&self) -> __BindgenOpaqueArray8<[u8; 8usize]> where ::Target: objc::Message + Sized, { @@ -48,7 +56,10 @@ pub trait IFooMultiGeneric< KeyType: 'static, ObjectType: 'static, >: Sized + std::ops::Deref { - unsafe fn objectForKey_(&self, key: u64) -> u64 + unsafe fn objectForKey_( + &self, + key: __BindgenOpaqueArray8<[u8; 8usize]>, + ) -> __BindgenOpaqueArray8<[u8; 8usize]> where ::Target: objc::Message + Sized, { diff --git a/bindgen-tests/tests/expectations/tests/only_bitfields.rs b/bindgen-tests/tests/expectations/tests/only_bitfields.rs index 5cd01b4485..9a73fc2fee 100644 --- a/bindgen-tests/tests/expectations/tests/only_bitfields.rs +++ b/bindgen-tests/tests/expectations/tests/only_bitfields.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,11 +126,28 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct C { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -107,6 +168,30 @@ impl C { } } #[inline] + pub unsafe fn a_raw(this: *const Self) -> bool { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_a_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b(&self) -> bool { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 7u8) as u8) } } @@ -118,6 +203,30 @@ impl C { } } #[inline] + pub unsafe fn b_raw(this: *const Self) -> bool { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 7u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 7u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); __bindgen_bitfield_unit diff --git a/bindgen-tests/tests/expectations/tests/opaque-template-inst-member.rs b/bindgen-tests/tests/expectations/tests/opaque-template-inst-member.rs index 4b070fa697..f765f01150 100644 --- a/bindgen-tests/tests/expectations/tests/opaque-template-inst-member.rs +++ b/bindgen-tests/tests/expectations/tests/opaque-template-inst-member.rs @@ -1,4 +1,12 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C)] +pub struct __BindgenOpaqueArray(pub T); +impl Default for __BindgenOpaqueArray<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct OpaqueTemplate { @@ -7,76 +15,46 @@ pub struct OpaqueTemplate { /** This should not end up deriving Debug/Hash because its `mBlah` field cannot derive Debug/Hash because the instantiation's definition cannot derive Debug/Hash.*/ #[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct ContainsOpaqueTemplate { - pub mBlah: [u32; 101usize], + pub mBlah: __BindgenOpaqueArray<[u32; 101usize]>, pub mBaz: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_ContainsOpaqueTemplate() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 408usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of ContainsOpaqueTemplate", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, + ][::std::mem::size_of::() - 408usize]; + [ "Alignment of ContainsOpaqueTemplate", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mBlah) as usize - ptr as usize }, - 0usize, + ][::std::mem::align_of::() - 4usize]; + [ "Offset of field: ContainsOpaqueTemplate::mBlah", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mBaz) as usize - ptr as usize }, - 404usize, + ][::std::mem::offset_of!(ContainsOpaqueTemplate, mBlah) - 0usize]; + [ "Offset of field: ContainsOpaqueTemplate::mBaz", - ); -} -impl Default for ContainsOpaqueTemplate { - fn default() -> Self { - let mut s = ::std::mem::MaybeUninit::::uninit(); - unsafe { - ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -impl ::std::cmp::PartialEq for ContainsOpaqueTemplate { - fn eq(&self, other: &ContainsOpaqueTemplate) -> bool { - &self.mBlah[..] == &other.mBlah[..] && self.mBaz == other.mBaz - } -} + ][::std::mem::offset_of!(ContainsOpaqueTemplate, mBaz) - 404usize]; +}; /** This should not end up deriving Debug/Hash either, for similar reasons, although we're exercising base member edges now.*/ #[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct InheritsOpaqueTemplate { - pub _base: [u8; 401usize], + pub _base: __BindgenOpaqueArray<[u8; 401usize]>, pub wow: *mut ::std::os::raw::c_char, } -#[test] -fn bindgen_test_layout_InheritsOpaqueTemplate() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 416usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of InheritsOpaqueTemplate", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, + ][::std::mem::size_of::() - 416usize]; + [ "Alignment of InheritsOpaqueTemplate", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).wow) as usize - ptr as usize }, - 408usize, + ][::std::mem::align_of::() - 8usize]; + [ "Offset of field: InheritsOpaqueTemplate::wow", - ); -} + ][::std::mem::offset_of!(InheritsOpaqueTemplate, wow) - 408usize]; +}; impl Default for InheritsOpaqueTemplate { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -86,8 +64,3 @@ impl Default for InheritsOpaqueTemplate { } } } -impl ::std::cmp::PartialEq for InheritsOpaqueTemplate { - fn eq(&self, other: &InheritsOpaqueTemplate) -> bool { - &self._base[..] == &other._base[..] && self.wow == other.wow - } -} diff --git a/bindgen-tests/tests/expectations/tests/opaque-tracing.rs b/bindgen-tests/tests/expectations/tests/opaque-tracing.rs index c181dc90d6..60d249a88c 100644 --- a/bindgen-tests/tests/expectations/tests/opaque-tracing.rs +++ b/bindgen-tests/tests/expectations/tests/opaque-tracing.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z3fooP9Container"] pub fn foo(c: *mut Container); } diff --git a/bindgen-tests/tests/expectations/tests/opencl_vector.rs b/bindgen-tests/tests/expectations/tests/opencl_vector.rs new file mode 100644 index 0000000000..3c2525c845 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/opencl_vector.rs @@ -0,0 +1,6 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub type float4 = [f32; 4usize]; +pub type float2 = [f32; 2usize]; +unsafe extern "C" { + pub fn foo(a: float2, b: float2) -> float4; +} diff --git a/bindgen-tests/tests/expectations/tests/operator.rs b/bindgen-tests/tests/expectations/tests/operator.rs index fa018724fc..ce5a652d8d 100644 --- a/bindgen-tests/tests/expectations/tests/operator.rs +++ b/bindgen-tests/tests/expectations/tests/operator.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z20operator_informationv"] pub fn operator_information() -> ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/operator_equals.rs b/bindgen-tests/tests/expectations/tests/operator_equals.rs new file mode 100644 index 0000000000..ff9f4fdd22 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/operator_equals.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct SomeClass { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of SomeClass"][::std::mem::size_of::() - 1usize]; + ["Alignment of SomeClass"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN9SomeClassaSERKS_"] + pub fn SomeClass_operatorequals( + this: *mut SomeClass, + another: *const SomeClass, + ) -> bool; +} +impl SomeClass { + #[inline] + pub unsafe fn operatorequals(&mut self, another: *const SomeClass) -> bool { + SomeClass_operatorequals(self, another) + } +} diff --git a/bindgen-tests/tests/expectations/tests/overloading.rs b/bindgen-tests/tests/expectations/tests/overloading.rs index 3e8fced8e7..96504b38eb 100644 --- a/bindgen-tests/tests/expectations/tests/overloading.rs +++ b/bindgen-tests/tests/expectations/tests/overloading.rs @@ -1,17 +1,17 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z8Evaluatec"] pub fn Evaluate(r: ::std::os::raw::c_char) -> bool; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z8Evaluateii"] pub fn Evaluate1(x: ::std::os::raw::c_int, y: ::std::os::raw::c_int) -> bool; } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3foo10MyFunctionEv"] pub fn foo_MyFunction(); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3bar10MyFunctionEv"] pub fn bar_MyFunction(); } diff --git a/bindgen-tests/tests/expectations/tests/packed-bitfield.rs b/bindgen-tests/tests/expectations/tests/packed-bitfield.rs index 852126ecfc..b5a734454a 100644 --- a/bindgen-tests/tests/expectations/tests/packed-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/packed-bitfield.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,11 +126,28 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C, packed)] #[derive(Debug, Default, Copy, Clone)] pub struct Date { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -107,6 +168,30 @@ impl Date { } } #[inline] + pub unsafe fn day_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 5u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_day_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 5u8, + val as u64, + ) + } + } + #[inline] pub fn month(&self) -> ::std::os::raw::c_uchar { unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 4u8) as u8) } } @@ -118,6 +203,30 @@ impl Date { } } #[inline] + pub unsafe fn month_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 5usize, 4u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_month_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 5usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn year(&self) -> ::std::os::raw::c_short { unsafe { ::std::mem::transmute(self._bitfield_1.get(9usize, 15u8) as u16) } } @@ -129,6 +238,31 @@ impl Date { } } #[inline] + pub unsafe fn year_raw(this: *const Self) -> ::std::os::raw::c_short { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 9usize, 15u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_year_raw(this: *mut Self, val: ::std::os::raw::c_short) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 9usize, + 15u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( day: ::std::os::raw::c_uchar, month: ::std::os::raw::c_uchar, diff --git a/bindgen-tests/tests/expectations/tests/packed-vtable.rs b/bindgen-tests/tests/expectations/tests/packed-vtable.rs index 362017a233..71e1956d88 100644 --- a/bindgen-tests/tests/expectations/tests/packed-vtable.rs +++ b/bindgen-tests/tests/expectations/tests/packed-vtable.rs @@ -6,25 +6,21 @@ pub struct PackedVtable__bindgen_vtable(::std::os::raw::c_void); pub struct PackedVtable { pub vtable_: *const PackedVtable__bindgen_vtable, } -#[test] -fn bindgen_test_layout_PackedVtable() { - assert_eq!(::std::mem::size_of::(), 8usize, "Size of PackedVtable"); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - "Alignment of PackedVtable", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of PackedVtable"][::std::mem::size_of::() - 8usize]; + ["Alignment of PackedVtable"][::std::mem::align_of::() - 1usize]; +}; impl Default for PackedVtable { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN12PackedVtableD1Ev"] pub fn PackedVtable_PackedVtable_destructor(this: *mut PackedVtable); } diff --git a/bindgen-tests/tests/expectations/tests/parm-union.rs b/bindgen-tests/tests/expectations/tests/parm-union.rs index 9c4f2f4e25..6dee4ec7d5 100644 --- a/bindgen-tests/tests/expectations/tests/parm-union.rs +++ b/bindgen-tests/tests/expectations/tests/parm-union.rs @@ -9,7 +9,7 @@ const _: () = { ["Size of Struct"][::std::mem::size_of::() - 1usize]; ["Alignment of Struct"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN6Struct8FunctionER5Union"] pub fn Struct_Function(this: *mut Struct, arg1: *mut Union); } diff --git a/bindgen-tests/tests/expectations/tests/partial-specialization-and-inheritance.rs b/bindgen-tests/tests/expectations/tests/partial-specialization-and-inheritance.rs index e7c9a38d7f..cba5cfbb52 100644 --- a/bindgen-tests/tests/expectations/tests/partial-specialization-and-inheritance.rs +++ b/bindgen-tests/tests/expectations/tests/partial-specialization-and-inheritance.rs @@ -1,4 +1,12 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C)] +pub struct __BindgenOpaqueArray(pub T); +impl Default for __BindgenOpaqueArray<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Base { @@ -14,9 +22,9 @@ pub struct Derived { pub struct Usage { pub _address: u8, } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN5Usage13static_memberE"] - pub static mut Usage_static_member: [u32; 2usize]; + pub static mut Usage_static_member: __BindgenOpaqueArray<[u32; 2usize]>; } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { diff --git a/bindgen-tests/tests/expectations/tests/pointer-attr.rs b/bindgen-tests/tests/expectations/tests/pointer-attr.rs index edb29dc499..4d7e250b9c 100644 --- a/bindgen-tests/tests/expectations/tests/pointer-attr.rs +++ b/bindgen-tests/tests/expectations/tests/pointer-attr.rs @@ -1,4 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn a(arg1: *const ::std::os::raw::c_char); } diff --git a/bindgen-tests/tests/expectations/tests/prefix-link-name-c.rs b/bindgen-tests/tests/expectations/tests/prefix-link-name-c.rs index e81a3b667d..cb1ebfa4f7 100644 --- a/bindgen-tests/tests/expectations/tests/prefix-link-name-c.rs +++ b/bindgen-tests/tests/expectations/tests/prefix-link-name-c.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}foo_bar"] pub fn bar() -> ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/prefix-link-name-cpp.rs b/bindgen-tests/tests/expectations/tests/prefix-link-name-cpp.rs index bf53473d88..07cacc5f7a 100644 --- a/bindgen-tests/tests/expectations/tests/prefix-link-name-cpp.rs +++ b/bindgen-tests/tests/expectations/tests/prefix-link-name-cpp.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}foo_foo"] pub fn baz_foo() -> ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/private_fields.rs b/bindgen-tests/tests/expectations/tests/private_fields.rs index 5a7bee9508..abb2886d39 100644 --- a/bindgen-tests/tests/expectations/tests/private_fields.rs +++ b/bindgen-tests/tests/expectations/tests/private_fields.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,6 +126,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] @@ -97,10 +159,9 @@ const _: () = { ["Offset of field: PubPriv::y"][::std::mem::offset_of!(PubPriv, y) - 4usize]; }; #[repr(C)] -#[repr(align(4))] #[derive(Debug, Default, Copy, Clone)] pub struct PrivateBitFields { - pub _bitfield_align_1: [u8; 0], + pub _bindgen_align: [u32; 0], _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub __bindgen_padding_0: [u8; 3usize], } @@ -124,6 +185,31 @@ impl PrivateBitFields { } } #[inline] + unsafe fn a_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 4u8) + as u32, + ) + } + } + #[inline] + unsafe fn set_a_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 4u8, + val as u64, + ) + } + } + #[inline] fn b(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u32) } } @@ -135,6 +221,31 @@ impl PrivateBitFields { } } #[inline] + unsafe fn b_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 4u8) + as u32, + ) + } + } + #[inline] + unsafe fn set_b_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 4usize, + 4u8, + val as u64, + ) + } + } + #[inline] fn new_bitfield_1( a: ::std::os::raw::c_uint, b: ::std::os::raw::c_uint, @@ -162,10 +273,9 @@ impl PrivateBitFields { } } #[repr(C)] -#[repr(align(4))] #[derive(Debug, Default, Copy, Clone)] pub struct PublicBitFields { - pub _bitfield_align_1: [u8; 0], + pub _bindgen_align: [u32; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub __bindgen_padding_0: [u8; 3usize], } @@ -187,6 +297,31 @@ impl PublicBitFields { } } #[inline] + pub unsafe fn a_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 4u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_a_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn b(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u32) } } @@ -198,6 +333,31 @@ impl PublicBitFields { } } #[inline] + pub unsafe fn b_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 4u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 4usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( a: ::std::os::raw::c_uint, b: ::std::os::raw::c_uint, @@ -225,10 +385,9 @@ impl PublicBitFields { } } #[repr(C)] -#[repr(align(4))] #[derive(Debug, Default, Copy, Clone)] pub struct MixedBitFields { - pub _bitfield_align_1: [u8; 0], + pub _bindgen_align: [u32; 0], _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub __bindgen_padding_0: [u8; 3usize], } @@ -250,6 +409,31 @@ impl MixedBitFields { } } #[inline] + unsafe fn a_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 4u8) + as u32, + ) + } + } + #[inline] + unsafe fn set_a_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 4u8, + val as u64, + ) + } + } + #[inline] pub fn d(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u32) } } @@ -261,6 +445,31 @@ impl MixedBitFields { } } #[inline] + pub unsafe fn d_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 4u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_d_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 4usize, + 4u8, + val as u64, + ) + } + } + #[inline] fn new_bitfield_1( a: ::std::os::raw::c_uint, d: ::std::os::raw::c_uint, @@ -416,7 +625,6 @@ pub struct Override { ///
b: ::std::os::raw::c_uint, private_c: ::std::os::raw::c_uint, - pub _bitfield_align_1: [u8; 0], _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, pub __bindgen_padding_0: u16, } @@ -443,6 +651,31 @@ impl Override { } } #[inline] + pub unsafe fn bf_a_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 4u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bf_a_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 4u8, + val as u64, + ) + } + } + #[inline] fn bf_b(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u32) } } @@ -454,6 +687,31 @@ impl Override { } } #[inline] + unsafe fn bf_b_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 4u8) + as u32, + ) + } + } + #[inline] + unsafe fn set_bf_b_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 4usize, + 4u8, + val as u64, + ) + } + } + #[inline] fn private_bf_c(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 4u8) as u32) } } @@ -465,6 +723,31 @@ impl Override { } } #[inline] + unsafe fn private_bf_c_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 8usize, 4u8) + as u32, + ) + } + } + #[inline] + unsafe fn set_private_bf_c_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 8usize, + 4u8, + val as u64, + ) + } + } + #[inline] fn new_bitfield_1( bf_a: ::std::os::raw::c_uint, bf_b: ::std::os::raw::c_uint, diff --git a/bindgen-tests/tests/expectations/tests/public-dtor.rs b/bindgen-tests/tests/expectations/tests/public-dtor.rs index c271125097..578d3e76a5 100644 --- a/bindgen-tests/tests/expectations/tests/public-dtor.rs +++ b/bindgen-tests/tests/expectations/tests/public-dtor.rs @@ -9,7 +9,7 @@ const _: () = { ["Size of cv_Foo"][::std::mem::size_of::() - 1usize]; ["Alignment of cv_Foo"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN2cv3FooD1Ev"] pub fn cv_Foo_Foo_destructor(this: *mut cv_Foo); } diff --git a/bindgen-tests/tests/expectations/tests/redeclaration.rs b/bindgen-tests/tests/expectations/tests/redeclaration.rs index 05b7aecd3e..736d379f01 100644 --- a/bindgen-tests/tests/expectations/tests/redeclaration.rs +++ b/bindgen-tests/tests/expectations/tests/redeclaration.rs @@ -1,4 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn foo(); } diff --git a/bindgen-tests/tests/expectations/tests/redundant-packed-and-align.rs b/bindgen-tests/tests/expectations/tests/redundant-packed-and-align.rs index 6e7db24870..05401e52ca 100644 --- a/bindgen-tests/tests/expectations/tests/redundant-packed-and-align.rs +++ b/bindgen-tests/tests/expectations/tests/redundant-packed-and-align.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,6 +126,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[repr(align(8))] @@ -104,11 +166,10 @@ const _: () = { ][::std::mem::offset_of!(redundant_packed, b) - 4usize]; }; #[repr(C)] -#[repr(align(8))] #[derive(Debug, Default, Copy, Clone)] pub struct redundant_packed_bitfield { + pub _bindgen_align: [u64; 0], pub a: [u8; 3usize], - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub c: u32, } @@ -140,6 +201,30 @@ impl redundant_packed_bitfield { } } #[inline] + pub unsafe fn b0_raw(this: *const Self) -> u8 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_b0_raw(this: *mut Self, val: u8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b1(&self) -> u8 { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u8) } } @@ -151,6 +236,30 @@ impl redundant_packed_bitfield { } } #[inline] + pub unsafe fn b1_raw(this: *const Self) -> u8 { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_b1_raw(this: *mut Self, val: u8) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1(b0: u8, b1: u8) -> __BindgenBitfieldUnit<[u8; 1usize]> { let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); __bindgen_bitfield_unit diff --git a/bindgen-tests/tests/expectations/tests/ref_argument_array.rs b/bindgen-tests/tests/expectations/tests/ref_argument_array.rs index de5f81c3c0..4928a185fe 100644 --- a/bindgen-tests/tests/expectations/tests/ref_argument_array.rs +++ b/bindgen-tests/tests/expectations/tests/ref_argument_array.rs @@ -26,7 +26,7 @@ impl Default for nsID { } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN4nsID16ToProvidedStringERA10_c"] pub fn nsID_ToProvidedString( this: *mut ::std::os::raw::c_void, diff --git a/bindgen-tests/tests/expectations/tests/references.rs b/bindgen-tests/tests/expectations/tests/references.rs new file mode 100644 index 0000000000..799e855793 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/references.rs @@ -0,0 +1,61 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Container { + pub normalPointer: *mut ::std::os::raw::c_int, + pub constPointer: *const ::std::os::raw::c_int, + pub normalRef: ::std::ptr::NonNull<::std::os::raw::c_int>, + pub constRef: ::std::ptr::NonNull<::std::os::raw::c_int>, + pub pointerRef: ::std::ptr::NonNull<*mut ::std::os::raw::c_int>, + pub constPointerRef: ::std::ptr::NonNull<*const ::std::os::raw::c_int>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Container"][::std::mem::size_of::() - 48usize]; + ["Alignment of Container"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: Container::normalPointer", + ][::std::mem::offset_of!(Container, normalPointer) - 0usize]; + [ + "Offset of field: Container::constPointer", + ][::std::mem::offset_of!(Container, constPointer) - 8usize]; + [ + "Offset of field: Container::normalRef", + ][::std::mem::offset_of!(Container, normalRef) - 16usize]; + [ + "Offset of field: Container::constRef", + ][::std::mem::offset_of!(Container, constRef) - 24usize]; + [ + "Offset of field: Container::pointerRef", + ][::std::mem::offset_of!(Container, pointerRef) - 32usize]; + [ + "Offset of field: Container::constPointerRef", + ][::std::mem::offset_of!(Container, constPointerRef) - 40usize]; +}; +impl Default for Container { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +unsafe extern "C" { + #[link_name = "\u{1}_Z20refReturningFunctionv"] + pub fn refReturningFunction() -> ::std::ptr::NonNull<::std::os::raw::c_int>; +} +unsafe extern "C" { + #[link_name = "\u{1}_Z20functionConsumingRefRifRKi"] + pub fn functionConsumingRef( + someRef: ::std::ptr::NonNull<::std::os::raw::c_int>, + normalArgument: f32, + constRef: ::std::ptr::NonNull<::std::os::raw::c_int>, + ); +} +unsafe extern "C" { + #[link_name = "\u{1}_Z27functionConsumingPointerRefRPi"] + pub fn functionConsumingPointerRef( + pointerRef: ::std::ptr::NonNull<*mut ::std::os::raw::c_int>, + ); +} diff --git a/bindgen-tests/tests/expectations/tests/repr-align.rs b/bindgen-tests/tests/expectations/tests/repr-align.rs index 6afc0ba859..867a28cc78 100644 --- a/bindgen-tests/tests/expectations/tests/repr-align.rs +++ b/bindgen-tests/tests/expectations/tests/repr-align.rs @@ -7,23 +7,13 @@ pub struct a { pub b: ::std::os::raw::c_int, pub c: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_a() { - const UNINIT: ::std::mem::MaybeUninit
= ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of a"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of a"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: a::b", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).c) as usize - ptr as usize }, - 4usize, - "Offset of field: a::c", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of a"][::std::mem::size_of::() - 8usize]; + ["Alignment of a"][::std::mem::align_of::() - 8usize]; + ["Offset of field: a::b"][::std::mem::offset_of!(a, b) - 0usize]; + ["Offset of field: a::c"][::std::mem::offset_of!(a, c) - 4usize]; +}; #[repr(C)] #[repr(align(8))] #[derive(Debug, Default, Copy, Clone)] @@ -31,20 +21,10 @@ pub struct b { pub b: ::std::os::raw::c_int, pub c: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_b() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of b"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of b"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: b::b", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).c) as usize - ptr as usize }, - 4usize, - "Offset of field: b::c", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of b"][::std::mem::size_of::() - 8usize]; + ["Alignment of b"][::std::mem::align_of::() - 8usize]; + ["Offset of field: b::b"][::std::mem::offset_of!(b, b) - 0usize]; + ["Offset of field: b::c"][::std::mem::offset_of!(b, c) - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/resolved_type_def_function.rs b/bindgen-tests/tests/expectations/tests/resolved_type_def_function.rs index 8fe7eb7da2..cfbab6b968 100644 --- a/bindgen-tests/tests/expectations/tests/resolved_type_def_function.rs +++ b/bindgen-tests/tests/expectations/tests/resolved_type_def_function.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub type FuncType = ::std::option::Option; -extern "C" { +unsafe extern "C" { pub fn Func(); } diff --git a/bindgen-tests/tests/expectations/tests/size_t_template.rs b/bindgen-tests/tests/expectations/tests/size_t_template.rs index e422131ca7..08ffa22750 100644 --- a/bindgen-tests/tests/expectations/tests/size_t_template.rs +++ b/bindgen-tests/tests/expectations/tests/size_t_template.rs @@ -1,8 +1,16 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C)] +pub struct __BindgenOpaqueArray(pub T); +impl Default for __BindgenOpaqueArray<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} #[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct C { - pub arr: [u32; 3usize], + pub arr: __BindgenOpaqueArray<[u32; 3usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { diff --git a/bindgen-tests/tests/expectations/tests/sorted_items.rs b/bindgen-tests/tests/expectations/tests/sorted_items.rs index 5f1505bd86..1c235fb31d 100644 --- a/bindgen-tests/tests/expectations/tests/sorted_items.rs +++ b/bindgen-tests/tests/expectations/tests/sorted_items.rs @@ -60,30 +60,30 @@ pub mod root { pub const NUMBER: root::ns::number = 42; #[allow(unused_imports)] use self::super::super::root; - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN2ns3fooEv"] pub fn foo() -> ::std::os::raw::c_int; } - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN2ns3barEi"] pub fn bar(x: root::ns::number) -> ::std::os::raw::c_int; } - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_ZN2ns3bazENS_5PointE"] pub fn baz(point: root::ns::Point) -> ::std::os::raw::c_int; } } #[allow(unused_imports)] use self::super::root; - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_Z3foov"] pub fn foo() -> ::std::os::raw::c_int; } - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_Z3bari"] pub fn bar(x: root::number) -> ::std::os::raw::c_int; } - extern "C" { + unsafe extern "C" { #[link_name = "\u{1}_Z3baz5Point"] pub fn baz(point: root::Point) -> ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/special-members.rs b/bindgen-tests/tests/expectations/tests/special-members.rs new file mode 100644 index 0000000000..4f54670c86 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/special-members.rs @@ -0,0 +1,51 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Debug, Default)] +pub struct A { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::() - 1usize]; + ["Alignment of A"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN1AC1Ev"] + pub fn A_A(this: *mut A); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN1AC1ERS_"] + pub fn A_A1(this: *mut A, arg1: *mut A); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN1AC1EOS_"] + pub fn A_A2(this: *mut A, arg1: *mut A); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN1AD1Ev"] + pub fn A_A_destructor(this: *mut A); +} +impl A { + #[inline] + pub unsafe fn new() -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + A_A(__bindgen_tmp.as_mut_ptr()); + __bindgen_tmp.assume_init() + } + #[inline] + pub unsafe fn new1(arg1: *mut A) -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + A_A1(__bindgen_tmp.as_mut_ptr(), arg1); + __bindgen_tmp.assume_init() + } + #[inline] + pub unsafe fn new2(arg1: *mut A) -> Self { + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + A_A2(__bindgen_tmp.as_mut_ptr(), arg1); + __bindgen_tmp.assume_init() + } + #[inline] + pub unsafe fn destruct(&mut self) { + A_A_destructor(self) + } +} diff --git a/bindgen-tests/tests/expectations/tests/specific_receiver.rs b/bindgen-tests/tests/expectations/tests/specific_receiver.rs new file mode 100644 index 0000000000..ec001b12ad --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/specific_receiver.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct Fish__bindgen_vtable { + pub Fish_swim: unsafe extern "C" fn(this: *mut Fish), +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Fish { + pub vtable_: *const Fish__bindgen_vtable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Fish"][::std::mem::size_of::() - 8usize]; + ["Alignment of Fish"][::std::mem::align_of::() - 8usize]; +}; +impl Default for Fish { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN4Fish4swimEv"] + pub fn Fish_swim(this: *mut Fish); +} diff --git a/bindgen-tests/tests/expectations/tests/stdint_typedef.rs b/bindgen-tests/tests/expectations/tests/stdint_typedef.rs index 8594727dfa..7cb1a2a8fb 100644 --- a/bindgen-tests/tests/expectations/tests/stdint_typedef.rs +++ b/bindgen-tests/tests/expectations/tests/stdint_typedef.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn fun() -> u64; } #[repr(C)] diff --git a/bindgen-tests/tests/expectations/tests/strings_array.rs b/bindgen-tests/tests/expectations/tests/strings_array.rs index 6f352b32ca..12543e59a8 100644 --- a/bindgen-tests/tests/expectations/tests/strings_array.rs +++ b/bindgen-tests/tests/expectations/tests/strings_array.rs @@ -1,4 +1,4 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -pub const MY_STRING_UTF8: &'static [u8; 14] = b"Hello, world!\0"; -pub const MY_STRING_INTERIOR_NULL: &'static [u8; 7] = b"Hello,\0"; -pub const MY_STRING_NON_UTF8: &'static [u8; 7] = b"ABCDE\xFF\0"; +pub const MY_STRING_UTF8: &[u8; 14] = b"Hello, world!\0"; +pub const MY_STRING_INTERIOR_NULL: &[u8; 7] = b"Hello,\0"; +pub const MY_STRING_NON_UTF8: &[u8; 7] = b"ABCDE\xFF\0"; diff --git a/bindgen-tests/tests/expectations/tests/strings_cstr2.rs b/bindgen-tests/tests/expectations/tests/strings_cstr2.rs new file mode 100644 index 0000000000..2ce21f4374 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/strings_cstr2.rs @@ -0,0 +1,4 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +pub const MY_STRING_UTF8: &::std::ffi::CStr = c"Hello, world!"; +pub const MY_STRING_INTERIOR_NULL: &::std::ffi::CStr = c"Hello,"; +pub const MY_STRING_NON_UTF8: &::std::ffi::CStr = c"ABCDE\xFF"; diff --git a/bindgen-tests/tests/expectations/tests/strings_cstr2_2018.rs b/bindgen-tests/tests/expectations/tests/strings_cstr2_2018.rs new file mode 100644 index 0000000000..ca089cf130 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/strings_cstr2_2018.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[allow(unsafe_code)] +pub const MY_STRING_UTF8: &::std::ffi::CStr = unsafe { + ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"Hello, world!\0") +}; +#[allow(unsafe_code)] +pub const MY_STRING_INTERIOR_NULL: &::std::ffi::CStr = unsafe { + ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"Hello,\0") +}; +#[allow(unsafe_code)] +pub const MY_STRING_NON_UTF8: &::std::ffi::CStr = unsafe { + ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"ABCDE\xFF\0") +}; diff --git a/bindgen-tests/tests/expectations/tests/struct_with_anon_union_1_0.rs b/bindgen-tests/tests/expectations/tests/struct_with_anon_union_1_0.rs deleted file mode 100644 index dda2d06eb8..0000000000 --- a/bindgen-tests/tests/expectations/tests/struct_with_anon_union_1_0.rs +++ /dev/null @@ -1,103 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo { - pub bar: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1 { - pub a: __BindgenUnionField<::std::os::raw::c_uint>, - pub b: __BindgenUnionField<::std::os::raw::c_ushort>, - pub bindgen_union_field: u32, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of foo__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of foo__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1::b", - ); -} -impl Clone for foo__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_foo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of foo"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of foo"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).bar) as usize - ptr as usize }, - 0usize, - "Offset of field: foo::bar", - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/struct_with_anon_unnamed_union_1_0.rs b/bindgen-tests/tests/expectations/tests/struct_with_anon_unnamed_union_1_0.rs deleted file mode 100644 index b9977c688b..0000000000 --- a/bindgen-tests/tests/expectations/tests/struct_with_anon_unnamed_union_1_0.rs +++ /dev/null @@ -1,96 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo { - pub __bindgen_anon_1: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1 { - pub a: __BindgenUnionField<::std::os::raw::c_uint>, - pub b: __BindgenUnionField<::std::os::raw::c_ushort>, - pub bindgen_union_field: u32, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of foo__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of foo__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1::b", - ); -} -impl Clone for foo__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_foo() { - assert_eq!(::std::mem::size_of::(), 4usize, "Size of foo"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of foo"); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs b/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs index fb21433415..a294c871d3 100644 --- a/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs +++ b/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,14 +126,30 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct bitfield { - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, pub e: ::std::os::raw::c_int, - pub _bitfield_align_2: [u32; 0], pub _bitfield_2: __BindgenBitfieldUnit<[u8; 8usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -111,6 +171,31 @@ impl bitfield { } } #[inline] + pub unsafe fn a_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_a_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn b(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 1u8) as u16) } } @@ -122,6 +207,31 @@ impl bitfield { } } #[inline] + pub unsafe fn b_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 1usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn c(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(2usize, 1u8) as u16) } } @@ -133,6 +243,31 @@ impl bitfield { } } #[inline] + pub unsafe fn c_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 1u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_c_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 2usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn d(&self) -> ::std::os::raw::c_ushort { unsafe { ::std::mem::transmute(self._bitfield_1.get(6usize, 2u8) as u16) } } @@ -144,6 +279,31 @@ impl bitfield { } } #[inline] + pub unsafe fn d_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 6usize, 2u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_d_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 6usize, + 2u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( a: ::std::os::raw::c_ushort, b: ::std::os::raw::c_ushort, @@ -201,6 +361,31 @@ impl bitfield { } } #[inline] + pub unsafe fn f_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 0usize, 2u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_f_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 0usize, + 2u8, + val as u64, + ) + } + } + #[inline] pub fn g(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_2.get(32usize, 32u8) as u32) } } @@ -212,6 +397,31 @@ impl bitfield { } } #[inline] + pub unsafe fn g_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 32usize, 32u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_g_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 8usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 32usize, + 32u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_2( f: ::std::os::raw::c_uint, g: ::std::os::raw::c_uint, diff --git a/bindgen-tests/tests/expectations/tests/struct_with_derive_debug.rs b/bindgen-tests/tests/expectations/tests/struct_with_derive_debug.rs index b472666081..f86fe6fb8f 100644 --- a/bindgen-tests/tests/expectations/tests/struct_with_derive_debug.rs +++ b/bindgen-tests/tests/expectations/tests/struct_with_derive_debug.rs @@ -4,39 +4,23 @@ pub struct LittleArray { pub a: [::std::os::raw::c_int; 32usize], } -#[test] -fn bindgen_test_layout_LittleArray() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 128usize, "Size of LittleArray"); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of LittleArray", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: LittleArray::a", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of LittleArray"][::std::mem::size_of::() - 128usize]; + ["Alignment of LittleArray"][::std::mem::align_of::() - 4usize]; + ["Offset of field: LittleArray::a"][::std::mem::offset_of!(LittleArray, a) - 0usize]; +}; #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct BigArray { pub a: [::std::os::raw::c_int; 33usize], } -#[test] -fn bindgen_test_layout_BigArray() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 132usize, "Size of BigArray"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of BigArray"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: BigArray::a", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of BigArray"][::std::mem::size_of::() - 132usize]; + ["Alignment of BigArray"][::std::mem::align_of::() - 4usize]; + ["Offset of field: BigArray::a"][::std::mem::offset_of!(BigArray, a) - 0usize]; +}; impl Default for BigArray { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -51,47 +35,27 @@ impl Default for BigArray { pub struct WithLittleArray { pub a: LittleArray, } -#[test] -fn bindgen_test_layout_WithLittleArray() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 128usize, - "Size of WithLittleArray", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of WithLittleArray", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of WithLittleArray"][::std::mem::size_of::() - 128usize]; + ["Alignment of WithLittleArray"][::std::mem::align_of::() - 4usize]; + [ "Offset of field: WithLittleArray::a", - ); -} + ][::std::mem::offset_of!(WithLittleArray, a) - 0usize]; +}; #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct WithBigArray { pub a: BigArray, } -#[test] -fn bindgen_test_layout_WithBigArray() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 132usize, "Size of WithBigArray"); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of WithBigArray", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of WithBigArray"][::std::mem::size_of::() - 132usize]; + ["Alignment of WithBigArray"][::std::mem::align_of::() - 4usize]; + [ "Offset of field: WithBigArray::a", - ); -} + ][::std::mem::offset_of!(WithBigArray, a) - 0usize]; +}; impl Default for WithBigArray { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); diff --git a/bindgen-tests/tests/expectations/tests/struct_with_large_array.rs b/bindgen-tests/tests/expectations/tests/struct_with_large_array.rs index eda7cadb46..df7a2192ed 100644 --- a/bindgen-tests/tests/expectations/tests/struct_with_large_array.rs +++ b/bindgen-tests/tests/expectations/tests/struct_with_large_array.rs @@ -1,21 +1,15 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct S { pub large_array: [::std::os::raw::c_char; 33usize], } -#[test] -fn bindgen_test_layout_S() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 33usize, "Size of S"); - assert_eq!(::std::mem::align_of::(), 1usize, "Alignment of S"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).large_array) as usize - ptr as usize }, - 0usize, - "Offset of field: S::large_array", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of S"][::std::mem::size_of::() - 33usize]; + ["Alignment of S"][::std::mem::align_of::() - 1usize]; + ["Offset of field: S::large_array"][::std::mem::offset_of!(S, large_array) - 0usize]; +}; impl Default for S { fn default() -> Self { let mut s = ::std::mem::MaybeUninit::::uninit(); @@ -26,6 +20,7 @@ impl Default for S { } } #[repr(C)] +#[derive(Debug, Hash, PartialEq, Eq)] pub struct ST { pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub large_array: [T; 33usize], diff --git a/bindgen-tests/tests/expectations/tests/struct_with_nesting_1_0.rs b/bindgen-tests/tests/expectations/tests/struct_with_nesting_1_0.rs deleted file mode 100644 index 0753326174..0000000000 --- a/bindgen-tests/tests/expectations/tests/struct_with_nesting_1_0.rs +++ /dev/null @@ -1,184 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo { - pub a: ::std::os::raw::c_uint, - pub __bindgen_anon_1: foo__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1 { - pub b: __BindgenUnionField<::std::os::raw::c_uint>, - pub __bindgen_anon_1: __BindgenUnionField, - pub __bindgen_anon_2: __BindgenUnionField, - pub bindgen_union_field: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1__bindgen_ty_1 { - pub c1: ::std::os::raw::c_ushort, - pub c2: ::std::os::raw::c_ushort, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of foo__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of foo__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).c1) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1__bindgen_ty_1::c1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).c2) as usize - ptr as usize }, - 2usize, - "Offset of field: foo__bindgen_ty_1__bindgen_ty_1::c2", - ); -} -impl Clone for foo__bindgen_ty_1__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1__bindgen_ty_2 { - pub d1: ::std::os::raw::c_uchar, - pub d2: ::std::os::raw::c_uchar, - pub d3: ::std::os::raw::c_uchar, - pub d4: ::std::os::raw::c_uchar, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1__bindgen_ty_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of foo__bindgen_ty_1__bindgen_ty_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - "Alignment of foo__bindgen_ty_1__bindgen_ty_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).d1) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1__bindgen_ty_2::d1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).d2) as usize - ptr as usize }, - 1usize, - "Offset of field: foo__bindgen_ty_1__bindgen_ty_2::d2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).d3) as usize - ptr as usize }, - 2usize, - "Offset of field: foo__bindgen_ty_1__bindgen_ty_2::d3", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).d4) as usize - ptr as usize }, - 3usize, - "Offset of field: foo__bindgen_ty_1__bindgen_ty_2::d4", - ); -} -impl Clone for foo__bindgen_ty_1__bindgen_ty_2 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of foo__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of foo__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1::b", - ); -} -impl Clone for foo__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_foo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of foo"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of foo"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: foo::a", - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/template.rs b/bindgen-tests/tests/expectations/tests/template.rs index aa2a7753e2..94678cb49e 100644 --- a/bindgen-tests/tests/expectations/tests/template.rs +++ b/bindgen-tests/tests/expectations/tests/template.rs @@ -31,7 +31,7 @@ impl Default for B { } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z3bar3FooIiiE"] pub fn bar(foo: Foo<::std::os::raw::c_int>); } diff --git a/bindgen-tests/tests/expectations/tests/template_instantiation_with_fn_local_type.rs b/bindgen-tests/tests/expectations/tests/template_instantiation_with_fn_local_type.rs index 0bf9cc6d82..085278e603 100644 --- a/bindgen-tests/tests/expectations/tests/template_instantiation_with_fn_local_type.rs +++ b/bindgen-tests/tests/expectations/tests/template_instantiation_with_fn_local_type.rs @@ -4,7 +4,7 @@ pub struct Foo { pub _address: u8, } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z1fv"] pub fn f(); } diff --git a/bindgen-tests/tests/expectations/tests/test_mixed_header_and_header_contents.rs b/bindgen-tests/tests/expectations/tests/test_mixed_header_and_header_contents.rs index a2910b9b24..e1872623bc 100644 --- a/bindgen-tests/tests/expectations/tests/test_mixed_header_and_header_contents.rs +++ b/bindgen-tests/tests/expectations/tests/test_mixed_header_and_header_contents.rs @@ -1,4 +1,4 @@ -extern "C" { +unsafe extern "C" { pub static mut foo: ::std::option::Option< unsafe extern "C" fn( x: ::std::os::raw::c_int, @@ -6,10 +6,10 @@ extern "C" { ) -> ::std::os::raw::c_int, >; } -extern "C" { +unsafe extern "C" { pub fn bar(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn bar2(b: *const ::std::os::raw::c_char) -> f32; } pub type Char = ::std::os::raw::c_char; diff --git a/bindgen-tests/tests/expectations/tests/test_multiple_header_calls_in_builder.rs b/bindgen-tests/tests/expectations/tests/test_multiple_header_calls_in_builder.rs index bcc27d259f..2e62ac902f 100644 --- a/bindgen-tests/tests/expectations/tests/test_multiple_header_calls_in_builder.rs +++ b/bindgen-tests/tests/expectations/tests/test_multiple_header_calls_in_builder.rs @@ -1,4 +1,4 @@ -extern "C" { +unsafe extern "C" { pub static mut foo: ::std::option::Option< unsafe extern "C" fn( x: ::std::os::raw::c_int, diff --git a/bindgen-tests/tests/expectations/tests/timex.rs b/bindgen-tests/tests/expectations/tests/timex.rs index a9f78066f0..f73b608de2 100644 --- a/bindgen-tests/tests/expectations/tests/timex.rs +++ b/bindgen-tests/tests/expectations/tests/timex.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,12 +126,29 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct timex { pub tai: ::std::os::raw::c_int, - pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 44usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -109,7 +170,6 @@ impl Default for timex { #[derive(Debug, Copy, Clone)] pub struct timex_named { pub tai: ::std::os::raw::c_int, - pub _bitfield_align_1: [u32; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 44usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -142,6 +202,31 @@ impl timex_named { } } #[inline] + pub unsafe fn a_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 32u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_a_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 32u8, + val as u64, + ) + } + } + #[inline] pub fn b(&self) -> ::std::os::raw::c_int { unsafe { ::std::mem::transmute(self._bitfield_1.get(32usize, 32u8) as u32) } } @@ -153,6 +238,31 @@ impl timex_named { } } #[inline] + pub unsafe fn b_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 32usize, 32u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 32usize, + 32u8, + val as u64, + ) + } + } + #[inline] pub fn c(&self) -> ::std::os::raw::c_int { unsafe { ::std::mem::transmute(self._bitfield_1.get(64usize, 32u8) as u32) } } @@ -164,6 +274,31 @@ impl timex_named { } } #[inline] + pub unsafe fn c_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 64usize, 32u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_c_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 64usize, + 32u8, + val as u64, + ) + } + } + #[inline] pub fn d(&self) -> ::std::os::raw::c_int { unsafe { ::std::mem::transmute(self._bitfield_1.get(96usize, 32u8) as u32) } } @@ -175,6 +310,31 @@ impl timex_named { } } #[inline] + pub unsafe fn d_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 96usize, 32u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_d_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 96usize, + 32u8, + val as u64, + ) + } + } + #[inline] pub fn e(&self) -> ::std::os::raw::c_int { unsafe { ::std::mem::transmute(self._bitfield_1.get(128usize, 32u8) as u32) } } @@ -186,6 +346,31 @@ impl timex_named { } } #[inline] + pub unsafe fn e_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 128usize, 32u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_e_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 128usize, + 32u8, + val as u64, + ) + } + } + #[inline] pub fn f(&self) -> ::std::os::raw::c_int { unsafe { ::std::mem::transmute(self._bitfield_1.get(160usize, 32u8) as u32) } } @@ -197,6 +382,31 @@ impl timex_named { } } #[inline] + pub unsafe fn f_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 160usize, 32u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_f_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 160usize, + 32u8, + val as u64, + ) + } + } + #[inline] pub fn g(&self) -> ::std::os::raw::c_int { unsafe { ::std::mem::transmute(self._bitfield_1.get(192usize, 32u8) as u32) } } @@ -208,6 +418,31 @@ impl timex_named { } } #[inline] + pub unsafe fn g_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 192usize, 32u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_g_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 192usize, + 32u8, + val as u64, + ) + } + } + #[inline] pub fn h(&self) -> ::std::os::raw::c_int { unsafe { ::std::mem::transmute(self._bitfield_1.get(224usize, 32u8) as u32) } } @@ -219,6 +454,31 @@ impl timex_named { } } #[inline] + pub unsafe fn h_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 224usize, 32u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_h_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 224usize, + 32u8, + val as u64, + ) + } + } + #[inline] pub fn i(&self) -> ::std::os::raw::c_int { unsafe { ::std::mem::transmute(self._bitfield_1.get(256usize, 32u8) as u32) } } @@ -230,6 +490,31 @@ impl timex_named { } } #[inline] + pub unsafe fn i_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 256usize, 32u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_i_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 256usize, + 32u8, + val as u64, + ) + } + } + #[inline] pub fn j(&self) -> ::std::os::raw::c_int { unsafe { ::std::mem::transmute(self._bitfield_1.get(288usize, 32u8) as u32) } } @@ -241,6 +526,31 @@ impl timex_named { } } #[inline] + pub unsafe fn j_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 288usize, 32u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_j_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 288usize, + 32u8, + val as u64, + ) + } + } + #[inline] pub fn k(&self) -> ::std::os::raw::c_int { unsafe { ::std::mem::transmute(self._bitfield_1.get(320usize, 32u8) as u32) } } @@ -251,4 +561,29 @@ impl timex_named { self._bitfield_1.set(320usize, 32u8, val as u64) } } + #[inline] + pub unsafe fn k_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 320usize, 32u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_k_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 44usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 320usize, + 32u8, + val as u64, + ) + } + } } diff --git a/bindgen-tests/tests/expectations/tests/transform-op.rs b/bindgen-tests/tests/expectations/tests/transform-op.rs index b53cea166a..7a12f2abb7 100644 --- a/bindgen-tests/tests/expectations/tests/transform-op.rs +++ b/bindgen-tests/tests/expectations/tests/transform-op.rs @@ -3,7 +3,7 @@ pub struct __BindgenUnionField(::std::marker::PhantomData); impl __BindgenUnionField { #[inline] - pub fn new() -> Self { + pub const fn new() -> Self { __BindgenUnionField(::std::marker::PhantomData) } #[inline] @@ -51,15 +51,15 @@ pub struct StylePoint { } impl Default for StylePoint { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } #[repr(C)] -#[derive(Debug, Default, Copy, Clone)] +#[repr(align(1))] pub struct StyleFoo { pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub __bindgen_anon_1: __BindgenUnionField, @@ -84,10 +84,10 @@ pub struct StyleFoo_Foo_Body { } impl Default for StyleFoo_Foo_Body { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } @@ -100,10 +100,10 @@ pub struct StyleFoo_Bar_Body { } impl Default for StyleFoo_Bar_Body { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } @@ -116,10 +116,10 @@ pub struct StyleFoo_Baz_Body { } impl Default for StyleFoo_Baz_Body { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } @@ -130,15 +130,23 @@ pub struct StyleFoo__bindgen_ty_1 { } impl Default for StyleFoo__bindgen_ty_1 { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl Default for StyleFoo { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } #[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct StyleBar { pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub tag: StyleBar_Tag, @@ -159,10 +167,10 @@ pub struct StyleBar_StyleBar1_Body { } impl Default for StyleBar_StyleBar1_Body { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } @@ -174,10 +182,10 @@ pub struct StyleBar_StyleBar2_Body { } impl Default for StyleBar_StyleBar2_Body { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } @@ -189,15 +197,15 @@ pub struct StyleBar_StyleBar3_Body { } impl Default for StyleBar_StyleBar3_Body { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } #[repr(C)] -#[derive(Debug, Default, Copy, Clone)] +#[repr(align(1))] pub struct StyleBar__bindgen_ty_1 { pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell>, pub bar1: __BindgenUnionField>, @@ -205,38 +213,39 @@ pub struct StyleBar__bindgen_ty_1 { pub bar3: __BindgenUnionField>, pub bindgen_union_field: [u8; 0usize], } +impl Default for StyleBar__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} impl Default for StyleBar { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } -#[test] -fn __bindgen_test_layout_StylePoint_open0_float_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of template specialization: StylePoint_open0_float_close0", - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, + ][::std::mem::size_of::>() - 8usize]; + [ "Align of template specialization: StylePoint_open0_float_close0", - ); -} -#[test] -fn __bindgen_test_layout_StylePoint_open0_float_close0_instantiation_1() { - assert_eq!( - ::std::mem::size_of::>(), - 8usize, + ][::std::mem::align_of::>() - 4usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ "Size of template specialization: StylePoint_open0_float_close0", - ); - assert_eq!( - ::std::mem::align_of::>(), - 4usize, + ][::std::mem::size_of::>() - 8usize]; + [ "Align of template specialization: StylePoint_open0_float_close0", - ); -} + ][::std::mem::align_of::>() - 4usize]; +}; diff --git a/bindgen-tests/tests/expectations/tests/type-referenced-by-allowlisted-function.rs b/bindgen-tests/tests/expectations/tests/type-referenced-by-allowlisted-function.rs index 8ddfaa7c68..6d1c43d9cc 100644 --- a/bindgen-tests/tests/expectations/tests/type-referenced-by-allowlisted-function.rs +++ b/bindgen-tests/tests/expectations/tests/type-referenced-by-allowlisted-function.rs @@ -12,6 +12,6 @@ const _: () = { "Offset of field: dl_phdr_info::x", ][::std::mem::offset_of!(dl_phdr_info, x) - 0usize]; }; -extern "C" { +unsafe extern "C" { pub fn dl_iterate_phdr(arg1: *mut dl_phdr_info) -> ::std::os::raw::c_int; } diff --git a/bindgen-tests/tests/expectations/tests/typedef-pointer-overlap.rs b/bindgen-tests/tests/expectations/tests/typedef-pointer-overlap.rs index f2376ed227..122059b4e1 100644 --- a/bindgen-tests/tests/expectations/tests/typedef-pointer-overlap.rs +++ b/bindgen-tests/tests/expectations/tests/typedef-pointer-overlap.rs @@ -55,33 +55,33 @@ pub type cat_ptr = *mut cat; pub const mad_scientist: mad = 0; pub type mad = ::std::os::raw::c_uint; pub type mad_ptr = *mut mad; -extern "C" { +unsafe extern "C" { pub fn takes_foo_ptr(arg1: foo_ptr); } -extern "C" { +unsafe extern "C" { pub fn takes_foo_struct(arg1: foo); } -extern "C" { +unsafe extern "C" { pub fn takes_bar_ptr(arg1: bar_ptr); } -extern "C" { +unsafe extern "C" { pub fn takes_bar_struct(arg1: bar); } -extern "C" { +unsafe extern "C" { pub fn takes_baz_ptr(arg1: baz_ptr); } -extern "C" { +unsafe extern "C" { pub fn takes_baz_struct(arg1: baz); } -extern "C" { +unsafe extern "C" { pub fn takes_cat_ptr(arg1: cat_ptr); } -extern "C" { +unsafe extern "C" { pub fn takes_cat_union(arg1: cat); } -extern "C" { +unsafe extern "C" { pub fn takes_mad_ptr(arg1: mad_ptr); } -extern "C" { +unsafe extern "C" { pub fn takes_mad_enum(arg1: mad); } diff --git a/bindgen-tests/tests/expectations/tests/typedefd-array-as-function-arg.rs b/bindgen-tests/tests/expectations/tests/typedefd-array-as-function-arg.rs index 792b243a7a..994b327da7 100644 --- a/bindgen-tests/tests/expectations/tests/typedefd-array-as-function-arg.rs +++ b/bindgen-tests/tests/expectations/tests/typedefd-array-as-function-arg.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub type myVector3 = [f32; 3usize]; -extern "C" { +unsafe extern "C" { pub fn modifyVectorFunc(v: *mut f32); } diff --git a/bindgen-tests/tests/expectations/tests/typeref_1_0.rs b/bindgen-tests/tests/expectations/tests/typeref_1_0.rs deleted file mode 100644 index 2cf1633a61..0000000000 --- a/bindgen-tests/tests/expectations/tests/typeref_1_0.rs +++ /dev/null @@ -1,175 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct mozilla_FragmentOrURL { - pub mIsLocalRef: bool, -} -#[test] -fn bindgen_test_layout_mozilla_FragmentOrURL() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 1usize, - "Size of mozilla_FragmentOrURL", - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - "Alignment of mozilla_FragmentOrURL", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mIsLocalRef) as usize - ptr as usize }, - 0usize, - "Offset of field: mozilla_FragmentOrURL::mIsLocalRef", - ); -} -impl Clone for mozilla_FragmentOrURL { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct mozilla_Position { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_mozilla_Position() { - assert_eq!( - ::std::mem::size_of::(), - 1usize, - "Size of mozilla_Position", - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - "Alignment of mozilla_Position", - ); -} -impl Clone for mozilla_Position { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct mozilla_StyleShapeSource { - pub __bindgen_anon_1: mozilla_StyleShapeSource__bindgen_ty_1, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct mozilla_StyleShapeSource__bindgen_ty_1 { - pub mPosition: __BindgenUnionField<*mut mozilla_Position>, - pub mFragmentOrURL: __BindgenUnionField<*mut mozilla_FragmentOrURL>, - pub bindgen_union_field: u64, -} -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct Bar { - pub mFoo: *mut nsFoo, -} -#[test] -fn bindgen_test_layout_Bar() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of Bar"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of Bar"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mFoo) as usize - ptr as usize }, - 0usize, - "Offset of field: Bar::mFoo", - ); -} -impl Clone for Bar { - fn clone(&self) -> Self { - *self - } -} -impl Default for Bar { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct nsFoo { - pub mBar: mozilla_StyleShapeSource, -} -#[test] -fn bindgen_test_layout_nsFoo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of nsFoo"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of nsFoo"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mBar) as usize - ptr as usize }, - 0usize, - "Offset of field: nsFoo::mBar", - ); -} -impl Clone for nsFoo { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn __bindgen_test_layout_mozilla_StyleShapeSource_open0_int_close0_instantiation() { - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of template specialization: mozilla_StyleShapeSource_open0_int_close0", - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Align of template specialization: mozilla_StyleShapeSource_open0_int_close0", - ); -} diff --git a/bindgen-tests/tests/expectations/tests/uncallable_functions.rs b/bindgen-tests/tests/expectations/tests/uncallable_functions.rs new file mode 100644 index 0000000000..fddb5d41fc --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/uncallable_functions.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct Test__bindgen_vtable { + pub Test_a: unsafe extern "C" fn(this: *mut Test), +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Test { + pub vtable_: *const Test__bindgen_vtable, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Test"][::std::mem::size_of::() - 8usize]; + ["Alignment of Test"][::std::mem::align_of::() - 8usize]; +}; +unsafe extern "C" { + #[link_name = "\u{1}_ZN4Test1bEv"] + pub fn Test_b(this: *mut Test); +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN4Test1cEv"] + pub fn Test_c(this: *mut Test); +} +impl Default for Test { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl Test { + #[inline] + pub unsafe fn b(&mut self) { + Test_b(self) + } + #[inline] + pub unsafe fn c(&mut self) { + Test_c(self) + } +} +unsafe extern "C" { + #[link_name = "\u{1}_ZN4Test1aEv"] + pub fn Test_a(this: *mut ::std::os::raw::c_void); +} diff --git a/bindgen-tests/tests/expectations/tests/union-align.rs b/bindgen-tests/tests/expectations/tests/union-align.rs index 2838ef34c3..bdb1bb376e 100644 --- a/bindgen-tests/tests/expectations/tests/union-align.rs +++ b/bindgen-tests/tests/expectations/tests/union-align.rs @@ -5,24 +5,18 @@ pub union Bar { pub foo: ::std::os::raw::c_uchar, } -#[test] -fn bindgen_test_layout_Bar() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 16usize, "Size of Bar"); - assert_eq!(::std::mem::align_of::(), 16usize, "Alignment of Bar"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).foo) as usize - ptr as usize }, - 0usize, - "Offset of field: Bar::foo", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Bar"][::std::mem::size_of::() - 16usize]; + ["Alignment of Bar"][::std::mem::align_of::() - 16usize]; + ["Offset of field: Bar::foo"][::std::mem::offset_of!(Bar, foo) - 0usize]; +}; impl Default for Bar { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } @@ -32,24 +26,18 @@ impl Default for Bar { pub union Baz { pub bar: Bar, } -#[test] -fn bindgen_test_layout_Baz() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 16usize, "Size of Baz"); - assert_eq!(::std::mem::align_of::(), 16usize, "Alignment of Baz"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).bar) as usize - ptr as usize }, - 0usize, - "Offset of field: Baz::bar", - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Baz"][::std::mem::size_of::() - 16usize]; + ["Alignment of Baz"][::std::mem::align_of::() - 16usize]; + ["Offset of field: Baz::bar"][::std::mem::offset_of!(Baz, bar) - 0usize]; +}; impl Default for Baz { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } diff --git a/bindgen-tests/tests/expectations/tests/union-in-ns_1_0.rs b/bindgen-tests/tests/expectations/tests/union-in-ns_1_0.rs deleted file mode 100644 index eac1df1a13..0000000000 --- a/bindgen-tests/tests/expectations/tests/union-in-ns_1_0.rs +++ /dev/null @@ -1,72 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)] -pub mod root { - #[repr(C)] - pub struct __BindgenUnionField(::std::marker::PhantomData); - impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } - } - impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } - } - impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } - } - impl ::std::marker::Copy for __BindgenUnionField {} - impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } - } - impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} - } - impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } - } - impl ::std::cmp::Eq for __BindgenUnionField {} - #[allow(unused_imports)] - use self::super::root; - #[repr(C)] - #[derive(Debug, Default, Copy)] - pub struct bar { - pub baz: root::__BindgenUnionField<::std::os::raw::c_int>, - pub bindgen_union_field: u32, - } - #[test] - fn bindgen_test_layout_bar() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of bar"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of bar"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).baz) as usize - ptr as usize }, - 0usize, - "Offset of field: bar::baz", - ); - } - impl Clone for bar { - fn clone(&self) -> Self { - *self - } - } -} diff --git a/bindgen-tests/tests/expectations/tests/union_bitfield.rs b/bindgen-tests/tests/expectations/tests/union_bitfield.rs index b529dcfbc8..8df0724738 100644 --- a/bindgen-tests/tests/expectations/tests/union_bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/union_bitfield.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,12 +126,29 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] -#[repr(align(4))] #[derive(Copy, Clone)] pub union U4 { - pub _bitfield_align_1: [u8; 0], + pub _bindgen_align: [u32; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -117,6 +178,31 @@ impl U4 { } } #[inline] + pub unsafe fn derp_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_derp_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( derp: ::std::os::raw::c_uint, ) -> __BindgenBitfieldUnit<[u8; 1usize]> { @@ -136,8 +222,8 @@ impl U4 { #[repr(C)] #[derive(Copy, Clone)] pub union B { - pub _bitfield_align_1: [u32; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, + pub _bindgen_align: [u32; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -166,22 +252,71 @@ impl B { } } #[inline] + pub unsafe fn foo_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 31u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_foo_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 31u8, + val as u64, + ) + } + } + #[inline] pub fn bar(&self) -> ::std::os::raw::c_uchar { - unsafe { ::std::mem::transmute(self._bitfield_1.get(31usize, 1u8) as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } } #[inline] pub fn set_bar(&mut self, val: ::std::os::raw::c_uchar) { unsafe { let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(31usize, 1u8, val as u64) + self._bitfield_1.set(0usize, 1u8, val as u64) + } + } + #[inline] + pub unsafe fn bar_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_bar_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 1usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 1u8, + val as u64, + ) } } #[inline] pub fn new_bitfield_1( foo: ::std::os::raw::c_uint, bar: ::std::os::raw::c_uchar, - ) -> __BindgenBitfieldUnit<[u8; 4usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 1usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, @@ -193,7 +328,7 @@ impl B { ); __bindgen_bitfield_unit .set( - 31usize, + 0usize, 1u8, { let bar: u8 = unsafe { ::std::mem::transmute(bar) }; diff --git a/bindgen-tests/tests/expectations/tests/union_bitfield_1_0.rs b/bindgen-tests/tests/expectations/tests/union_bitfield_1_0.rs deleted file mode 100644 index c2c7173bfe..0000000000 --- a/bindgen-tests/tests/expectations/tests/union_bitfield_1_0.rs +++ /dev/null @@ -1,281 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct __BindgenBitfieldUnit { - storage: Storage, -} -impl __BindgenBitfieldUnit { - #[inline] - pub fn new(storage: Storage) -> Self { - Self { storage } - } -} -impl __BindgenBitfieldUnit -where - Storage: AsRef<[u8]> + AsMut<[u8]>, -{ - #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; - let bit_index = if cfg!(target_endian = "big") { - 7 - (index % 8) - } else { - index % 8 - }; - let mask = 1 << bit_index; - byte & mask == mask - } - #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; - let bit_index = if cfg!(target_endian = "big") { - 7 - (index % 8) - } else { - index % 8 - }; - let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } - } - #[inline] - pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { - debug_assert!(bit_width <= 64); - debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); - debug_assert!( - (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), - ); - let mut val = 0; - for i in 0..(bit_width as usize) { - if self.get_bit(i + bit_offset) { - let index = if cfg!(target_endian = "big") { - bit_width as usize - 1 - i - } else { - i - }; - val |= 1 << index; - } - } - val - } - #[inline] - pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { - debug_assert!(bit_width <= 64); - debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); - debug_assert!( - (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), - ); - for i in 0..(bit_width as usize) { - let mask = 1 << i; - let val_bit_is_set = val & mask == mask; - let index = if cfg!(target_endian = "big") { - bit_width as usize - 1 - i - } else { - i - }; - self.set_bit(index + bit_offset, val_bit_is_set); - } - } -} -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct U4 { - pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenUnionField<__BindgenBitfieldUnit<[u8; 1usize]>>, - pub bindgen_union_field: u32, -} -#[test] -fn bindgen_test_layout_U4() { - assert_eq!(::std::mem::size_of::(), 4usize, "Size of U4"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of U4"); -} -impl Clone for U4 { - fn clone(&self) -> Self { - *self - } -} -impl U4 { - #[inline] - pub fn derp(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.as_ref().get(0usize, 1u8) as u32) - } - } - #[inline] - pub fn set_derp(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.as_mut().set(0usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - derp: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); - __bindgen_bitfield_unit - .set( - 0usize, - 1u8, - { - let derp: u32 = unsafe { ::std::mem::transmute(derp) }; - derp as u64 - }, - ); - __bindgen_bitfield_unit - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct B { - pub _bitfield_align_1: [u32; 0], - pub _bitfield_1: __BindgenUnionField<__BindgenBitfieldUnit<[u8; 4usize]>>, - pub bindgen_union_field: u32, -} -#[test] -fn bindgen_test_layout_B() { - assert_eq!(::std::mem::size_of::(), 4usize, "Size of B"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of B"); -} -impl Clone for B { - fn clone(&self) -> Self { - *self - } -} -impl B { - #[inline] - pub fn foo(&self) -> ::std::os::raw::c_uint { - unsafe { - ::std::mem::transmute(self._bitfield_1.as_ref().get(0usize, 31u8) as u32) - } - } - #[inline] - pub fn set_foo(&mut self, val: ::std::os::raw::c_uint) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.as_mut().set(0usize, 31u8, val as u64) - } - } - #[inline] - pub fn bar(&self) -> ::std::os::raw::c_uchar { - unsafe { - ::std::mem::transmute(self._bitfield_1.as_ref().get(31usize, 1u8) as u8) - } - } - #[inline] - pub fn set_bar(&mut self, val: ::std::os::raw::c_uchar) { - unsafe { - let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.as_mut().set(31usize, 1u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - foo: ::std::os::raw::c_uint, - bar: ::std::os::raw::c_uchar, - ) -> __BindgenBitfieldUnit<[u8; 4usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); - __bindgen_bitfield_unit - .set( - 0usize, - 31u8, - { - let foo: u32 = unsafe { ::std::mem::transmute(foo) }; - foo as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 31usize, - 1u8, - { - let bar: u8 = unsafe { ::std::mem::transmute(bar) }; - bar as u64 - }, - ); - __bindgen_bitfield_unit - } -} -#[repr(C)] -#[derive(Copy)] -pub struct HasBigBitfield { - pub _bitfield_align_1: [u64; 0], - pub _bitfield_1: __BindgenUnionField<__BindgenBitfieldUnit<[u8; 16usize]>>, - pub bindgen_union_field: [u8; 16usize], -} -#[test] -fn bindgen_test_layout_HasBigBitfield() { - assert_eq!( - ::std::mem::size_of::(), - 16usize, - "Size of HasBigBitfield", - ); -} -impl Clone for HasBigBitfield { - fn clone(&self) -> Self { - *self - } -} -impl Default for HasBigBitfield { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -impl ::std::cmp::PartialEq for HasBigBitfield { - fn eq(&self, other: &HasBigBitfield) -> bool { - &self.bindgen_union_field[..] == &other.bindgen_union_field[..] - } -} diff --git a/bindgen-tests/tests/expectations/tests/union_dtor.rs b/bindgen-tests/tests/expectations/tests/union_dtor.rs index 168b0a0b1e..3b89587098 100644 --- a/bindgen-tests/tests/expectations/tests/union_dtor.rs +++ b/bindgen-tests/tests/expectations/tests/union_dtor.rs @@ -15,7 +15,7 @@ const _: () = { "Offset of field: UnionWithDtor::mBar", ][::std::mem::offset_of!(UnionWithDtor, mBar) - 0usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN13UnionWithDtorD1Ev"] pub fn UnionWithDtor_UnionWithDtor_destructor(this: *mut UnionWithDtor); } diff --git a/bindgen-tests/tests/expectations/tests/union_dtor_1_0.rs b/bindgen-tests/tests/expectations/tests/union_dtor_1_0.rs deleted file mode 100644 index e9c777df94..0000000000 --- a/bindgen-tests/tests/expectations/tests/union_dtor_1_0.rs +++ /dev/null @@ -1,82 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default)] -pub struct UnionWithDtor { - pub mFoo: __BindgenUnionField<::std::os::raw::c_int>, - pub mBar: __BindgenUnionField<*mut ::std::os::raw::c_void>, - pub bindgen_union_field: u64, -} -#[test] -fn bindgen_test_layout_UnionWithDtor() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of UnionWithDtor"); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of UnionWithDtor", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mFoo) as usize - ptr as usize }, - 0usize, - "Offset of field: UnionWithDtor::mFoo", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mBar) as usize - ptr as usize }, - 0usize, - "Offset of field: UnionWithDtor::mBar", - ); -} -extern "C" { - #[link_name = "\u{1}_ZN13UnionWithDtorD1Ev"] - pub fn UnionWithDtor_UnionWithDtor_destructor(this: *mut UnionWithDtor); -} -impl UnionWithDtor { - #[inline] - pub unsafe fn destruct(&mut self) { - UnionWithDtor_UnionWithDtor_destructor(self) - } -} diff --git a/bindgen-tests/tests/expectations/tests/union_fields_1_0.rs b/bindgen-tests/tests/expectations/tests/union_fields_1_0.rs deleted file mode 100644 index 9cf2f09832..0000000000 --- a/bindgen-tests/tests/expectations/tests/union_fields_1_0.rs +++ /dev/null @@ -1,83 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq)] -pub struct nsStyleUnion { - pub mInt: __BindgenUnionField<::std::os::raw::c_int>, - pub mFloat: __BindgenUnionField, - pub mPointer: __BindgenUnionField<*mut ::std::os::raw::c_void>, - pub bindgen_union_field: u64, -} -#[test] -fn bindgen_test_layout_nsStyleUnion() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of nsStyleUnion"); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - "Alignment of nsStyleUnion", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mInt) as usize - ptr as usize }, - 0usize, - "Offset of field: nsStyleUnion::mInt", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mFloat) as usize - ptr as usize }, - 0usize, - "Offset of field: nsStyleUnion::mFloat", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mPointer) as usize - ptr as usize }, - 0usize, - "Offset of field: nsStyleUnion::mPointer", - ); -} -impl Clone for nsStyleUnion { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_1_0.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_1_0.rs deleted file mode 100644 index 7ea38b8bae..0000000000 --- a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_1_0.rs +++ /dev/null @@ -1,103 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo { - pub bar: __BindgenUnionField, - pub bindgen_union_field: [u32; 2usize], -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1 { - pub a: ::std::os::raw::c_uint, - pub b: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, - "Size of foo__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of foo__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 4usize, - "Offset of field: foo__bindgen_ty_1::b", - ); -} -impl Clone for foo__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_foo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 8usize, "Size of foo"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of foo"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).bar) as usize - ptr as usize }, - 0usize, - "Offset of field: foo::bar", - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs index f850f6a3da..a1b61c035d 100644 --- a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,6 +126,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(C)] #[derive(Copy, Clone)] @@ -92,7 +154,7 @@ pub union foo { #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct foo__bindgen_ty_1 { - pub _bitfield_align_1: [u32; 0], + pub _bindgen_align: [u32; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -115,6 +177,31 @@ impl foo__bindgen_ty_1 { } } #[inline] + pub unsafe fn b_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 7u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_b_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 7u8, + val as u64, + ) + } + } + #[inline] pub fn c(&self) -> ::std::os::raw::c_int { unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 25u8) as u32) } } @@ -126,6 +213,31 @@ impl foo__bindgen_ty_1 { } } #[inline] + pub unsafe fn c_raw(this: *const Self) -> ::std::os::raw::c_int { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 7usize, 25u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_c_raw(this: *mut Self, val: ::std::os::raw::c_int) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 7usize, + 25u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( b: ::std::os::raw::c_int, c: ::std::os::raw::c_int, diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs deleted file mode 100644 index ce81f8a04e..0000000000 --- a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs +++ /dev/null @@ -1,226 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct __BindgenBitfieldUnit { - storage: Storage, -} -impl __BindgenBitfieldUnit { - #[inline] - pub fn new(storage: Storage) -> Self { - Self { storage } - } -} -impl __BindgenBitfieldUnit -where - Storage: AsRef<[u8]> + AsMut<[u8]>, -{ - #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; - let bit_index = if cfg!(target_endian = "big") { - 7 - (index % 8) - } else { - index % 8 - }; - let mask = 1 << bit_index; - byte & mask == mask - } - #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; - let bit_index = if cfg!(target_endian = "big") { - 7 - (index % 8) - } else { - index % 8 - }; - let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } - } - #[inline] - pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { - debug_assert!(bit_width <= 64); - debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); - debug_assert!( - (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), - ); - let mut val = 0; - for i in 0..(bit_width as usize) { - if self.get_bit(i + bit_offset) { - let index = if cfg!(target_endian = "big") { - bit_width as usize - 1 - i - } else { - i - }; - val |= 1 << index; - } - } - val - } - #[inline] - pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { - debug_assert!(bit_width <= 64); - debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); - debug_assert!( - (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), - ); - for i in 0..(bit_width as usize) { - let mask = 1 << i; - let val_bit_is_set = val & mask == mask; - let index = if cfg!(target_endian = "big") { - bit_width as usize - 1 - i - } else { - i - }; - self.set_bit(index + bit_offset, val_bit_is_set); - } - } -} -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo { - pub a: __BindgenUnionField<::std::os::raw::c_int>, - pub __bindgen_anon_1: __BindgenUnionField, - pub bindgen_union_field: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1 { - pub _bitfield_align_1: [u32; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of foo__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of foo__bindgen_ty_1", - ); -} -impl Clone for foo__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -impl foo__bindgen_ty_1 { - #[inline] - pub fn b(&self) -> ::std::os::raw::c_int { - unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 7u8) as u32) } - } - #[inline] - pub fn set_b(&mut self, val: ::std::os::raw::c_int) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(0usize, 7u8, val as u64) - } - } - #[inline] - pub fn c(&self) -> ::std::os::raw::c_int { - unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 25u8) as u32) } - } - #[inline] - pub fn set_c(&mut self, val: ::std::os::raw::c_int) { - unsafe { - let val: u32 = ::std::mem::transmute(val); - self._bitfield_1.set(7usize, 25u8, val as u64) - } - } - #[inline] - pub fn new_bitfield_1( - b: ::std::os::raw::c_int, - c: ::std::os::raw::c_int, - ) -> __BindgenBitfieldUnit<[u8; 4usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); - __bindgen_bitfield_unit - .set( - 0usize, - 7u8, - { - let b: u32 = unsafe { ::std::mem::transmute(b) }; - b as u64 - }, - ); - __bindgen_bitfield_unit - .set( - 7usize, - 25u8, - { - let c: u32 = unsafe { ::std::mem::transmute(c) }; - c as u64 - }, - ); - __bindgen_bitfield_unit - } -} -#[test] -fn bindgen_test_layout_foo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of foo"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of foo"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: foo::a", - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_union_1_0.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_union_1_0.rs deleted file mode 100644 index ad6d9c7e16..0000000000 --- a/bindgen-tests/tests/expectations/tests/union_with_anon_union_1_0.rs +++ /dev/null @@ -1,104 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo { - pub bar: __BindgenUnionField, - pub bindgen_union_field: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1 { - pub a: __BindgenUnionField<::std::os::raw::c_uint>, - pub b: __BindgenUnionField<::std::os::raw::c_ushort>, - pub bindgen_union_field: u32, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of foo__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of foo__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1::b", - ); -} -impl Clone for foo__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_foo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of foo"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of foo"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).bar) as usize - ptr as usize }, - 0usize, - "Offset of field: foo::bar", - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_unnamed_struct_1_0.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_unnamed_struct_1_0.rs deleted file mode 100644 index 20ceaee90c..0000000000 --- a/bindgen-tests/tests/expectations/tests/union_with_anon_unnamed_struct_1_0.rs +++ /dev/null @@ -1,116 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct pixel { - pub rgba: __BindgenUnionField<::std::os::raw::c_uint>, - pub __bindgen_anon_1: __BindgenUnionField, - pub bindgen_union_field: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct pixel__bindgen_ty_1 { - pub r: ::std::os::raw::c_uchar, - pub g: ::std::os::raw::c_uchar, - pub b: ::std::os::raw::c_uchar, - pub a: ::std::os::raw::c_uchar, -} -#[test] -fn bindgen_test_layout_pixel__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of pixel__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - "Alignment of pixel__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).r) as usize - ptr as usize }, - 0usize, - "Offset of field: pixel__bindgen_ty_1::r", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).g) as usize - ptr as usize }, - 1usize, - "Offset of field: pixel__bindgen_ty_1::g", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 2usize, - "Offset of field: pixel__bindgen_ty_1::b", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 3usize, - "Offset of field: pixel__bindgen_ty_1::a", - ); -} -impl Clone for pixel__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_pixel() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of pixel"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of pixel"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).rgba) as usize - ptr as usize }, - 0usize, - "Offset of field: pixel::rgba", - ); -} -impl Clone for pixel { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_unnamed_union_1_0.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_unnamed_union_1_0.rs deleted file mode 100644 index 561c7f8071..0000000000 --- a/bindgen-tests/tests/expectations/tests/union_with_anon_unnamed_union_1_0.rs +++ /dev/null @@ -1,105 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo { - pub a: __BindgenUnionField<::std::os::raw::c_uint>, - pub __bindgen_anon_1: __BindgenUnionField, - pub bindgen_union_field: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1 { - pub b: __BindgenUnionField<::std::os::raw::c_ushort>, - pub c: __BindgenUnionField<::std::os::raw::c_uchar>, - pub bindgen_union_field: u16, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 2usize, - "Size of foo__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of foo__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1::b", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).c) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1::c", - ); -} -impl Clone for foo__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_foo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of foo"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of foo"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: foo::a", - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/union_with_big_member_1_0.rs b/bindgen-tests/tests/expectations/tests/union_with_big_member_1_0.rs deleted file mode 100644 index 14a68fc0bf..0000000000 --- a/bindgen-tests/tests/expectations/tests/union_with_big_member_1_0.rs +++ /dev/null @@ -1,165 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Copy)] -pub struct WithBigArray { - pub a: __BindgenUnionField<::std::os::raw::c_int>, - pub b: __BindgenUnionField<[::std::os::raw::c_int; 33usize]>, - pub bindgen_union_field: [u32; 33usize], -} -#[test] -fn bindgen_test_layout_WithBigArray() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 132usize, "Size of WithBigArray"); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of WithBigArray", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: WithBigArray::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: WithBigArray::b", - ); -} -impl Clone for WithBigArray { - fn clone(&self) -> Self { - *self - } -} -impl Default for WithBigArray { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct WithBigArray2 { - pub a: __BindgenUnionField<::std::os::raw::c_int>, - pub b: __BindgenUnionField<[::std::os::raw::c_char; 33usize]>, - pub bindgen_union_field: [u32; 9usize], -} -#[test] -fn bindgen_test_layout_WithBigArray2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 36usize, "Size of WithBigArray2"); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of WithBigArray2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: WithBigArray2::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: WithBigArray2::b", - ); -} -impl Clone for WithBigArray2 { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Copy)] -pub struct WithBigMember { - pub a: __BindgenUnionField<::std::os::raw::c_int>, - pub b: __BindgenUnionField, - pub bindgen_union_field: [u32; 33usize], -} -#[test] -fn bindgen_test_layout_WithBigMember() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 132usize, - "Size of WithBigMember", - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - "Alignment of WithBigMember", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: WithBigMember::a", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 0usize, - "Offset of field: WithBigMember::b", - ); -} -impl Clone for WithBigMember { - fn clone(&self) -> Self { - *self - } -} -impl Default for WithBigMember { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} diff --git a/bindgen-tests/tests/expectations/tests/union_with_nesting_1_0.rs b/bindgen-tests/tests/expectations/tests/union_with_nesting_1_0.rs deleted file mode 100644 index 22b902d82c..0000000000 --- a/bindgen-tests/tests/expectations/tests/union_with_nesting_1_0.rs +++ /dev/null @@ -1,166 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::std::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::std::mem::transmute(self) - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo { - pub a: __BindgenUnionField<::std::os::raw::c_uint>, - pub __bindgen_anon_1: __BindgenUnionField, - pub bindgen_union_field: u32, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1 { - pub __bindgen_anon_1: foo__bindgen_ty_1__bindgen_ty_1, - pub __bindgen_anon_2: foo__bindgen_ty_1__bindgen_ty_2, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1__bindgen_ty_1 { - pub b1: __BindgenUnionField<::std::os::raw::c_ushort>, - pub b2: __BindgenUnionField<::std::os::raw::c_ushort>, - pub bindgen_union_field: u16, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1__bindgen_ty_1() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 2usize, - "Size of foo__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of foo__bindgen_ty_1__bindgen_ty_1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b1) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1__bindgen_ty_1::b1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).b2) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1__bindgen_ty_1::b2", - ); -} -impl Clone for foo__bindgen_ty_1__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct foo__bindgen_ty_1__bindgen_ty_2 { - pub c1: __BindgenUnionField<::std::os::raw::c_ushort>, - pub c2: __BindgenUnionField<::std::os::raw::c_ushort>, - pub bindgen_union_field: u16, -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1__bindgen_ty_2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 2usize, - "Size of foo__bindgen_ty_1__bindgen_ty_2", - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of foo__bindgen_ty_1__bindgen_ty_2", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).c1) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1__bindgen_ty_2::c1", - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).c2) as usize - ptr as usize }, - 0usize, - "Offset of field: foo__bindgen_ty_1__bindgen_ty_2::c2", - ); -} -impl Clone for foo__bindgen_ty_1__bindgen_ty_2 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_foo__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::(), - 4usize, - "Size of foo__bindgen_ty_1", - ); - assert_eq!( - ::std::mem::align_of::(), - 2usize, - "Alignment of foo__bindgen_ty_1", - ); -} -impl Clone for foo__bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -#[test] -fn bindgen_test_layout_foo() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of foo"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of foo"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: foo::a", - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/union_template_1_0.rs b/bindgen-tests/tests/expectations/tests/union_with_zero_sized_array.rs similarity index 55% rename from bindgen-tests/tests/expectations/tests/union_template_1_0.rs rename to bindgen-tests/tests/expectations/tests/union_with_zero_sized_array.rs index 4ebad2a2e2..aa23fcd734 100644 --- a/bindgen-tests/tests/expectations/tests/union_template_1_0.rs +++ b/bindgen-tests/tests/expectations/tests/union_with_zero_sized_array.rs @@ -3,7 +3,7 @@ pub struct __BindgenUnionField(::std::marker::PhantomData); impl __BindgenUnionField { #[inline] - pub fn new() -> Self { + pub const fn new() -> Self { __BindgenUnionField(::std::marker::PhantomData) } #[inline] @@ -43,30 +43,26 @@ impl ::std::cmp::PartialEq for __BindgenUnionField { } impl ::std::cmp::Eq for __BindgenUnionField {} #[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct NastyStruct { - pub mIsSome: bool, - pub mStorage: NastyStruct__bindgen_ty_1, - pub __bindgen_anon_1: NastyStruct__bindgen_ty_2, +pub struct U { + pub d0: __BindgenUnionField<[::std::os::raw::c_char; 0usize]>, + pub d1: __BindgenUnionField<[::std::os::raw::c_char; 1usize]>, + pub d2: __BindgenUnionField<[::std::os::raw::c_char; 2usize]>, + pub bindgen_union_field: [u8; 2usize], } -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct NastyStruct__bindgen_ty_1 { - pub mFoo: __BindgenUnionField<*mut ::std::os::raw::c_void>, - pub mDummy: __BindgenUnionField<::std::os::raw::c_ulong>, - pub bindgen_union_field: u64, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct NastyStruct__bindgen_ty_2 { - pub wat: __BindgenUnionField<::std::os::raw::c_short>, - pub wut: __BindgenUnionField<*mut ::std::os::raw::c_int>, - pub bindgen_union_field: u64, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Whatever { - pub mTPtr: __BindgenUnionField<*mut ::std::os::raw::c_void>, - pub mInt: __BindgenUnionField<::std::os::raw::c_int>, - pub bindgen_union_field: u64, +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of U"][::std::mem::size_of::() - 2usize]; + ["Alignment of U"][::std::mem::align_of::() - 1usize]; + ["Offset of field: U::d0"][::std::mem::offset_of!(U, d0) - 0usize]; + ["Offset of field: U::d1"][::std::mem::offset_of!(U, d1) - 0usize]; + ["Offset of field: U::d2"][::std::mem::offset_of!(U, d2) - 0usize]; +}; +impl Default for U { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } } diff --git a/bindgen-tests/tests/expectations/tests/unknown_attr.rs b/bindgen-tests/tests/expectations/tests/unknown_attr.rs index bdfebb29dc..d749dad977 100644 --- a/bindgen-tests/tests/expectations/tests/unknown_attr.rs +++ b/bindgen-tests/tests/expectations/tests/unknown_attr.rs @@ -1,10 +1,18 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C, align(8))] +pub struct __BindgenOpaqueArray8(pub T); +impl Default for __BindgenOpaqueArray8<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} #[repr(C)] #[repr(align(16))] #[derive(Debug, Default, Copy, Clone)] pub struct max_align_t { pub __clang_max_align_nonce1: ::std::os::raw::c_longlong, - pub __bindgen_padding_0: u64, + pub __bindgen_padding_0: __BindgenOpaqueArray8<[u8; 8usize]>, pub __clang_max_align_nonce2: ::std::os::raw::c_longlong, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] diff --git a/bindgen-tests/tests/expectations/tests/unsorted-items.rs b/bindgen-tests/tests/expectations/tests/unsorted-items.rs index fca5715533..7d31c222a1 100644 --- a/bindgen-tests/tests/expectations/tests/unsorted-items.rs +++ b/bindgen-tests/tests/expectations/tests/unsorted-items.rs @@ -1,9 +1,9 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn foo() -> ::std::os::raw::c_int; } pub type number = ::std::os::raw::c_int; -extern "C" { +unsafe extern "C" { pub fn bar(x: number) -> ::std::os::raw::c_int; } #[repr(C)] @@ -32,7 +32,7 @@ const _: () = { ["Offset of field: Angle::a"][::std::mem::offset_of!(Angle, a) - 0usize]; ["Offset of field: Angle::b"][::std::mem::offset_of!(Angle, b) - 4usize]; }; -extern "C" { +unsafe extern "C" { pub fn baz(point: Point) -> ::std::os::raw::c_int; } pub const NUMBER: number = 42; diff --git a/bindgen-tests/tests/expectations/tests/use-core.rs b/bindgen-tests/tests/expectations/tests/use-core.rs index e7b3ce8982..8d495459a0 100644 --- a/bindgen-tests/tests/expectations/tests/use-core.rs +++ b/bindgen-tests/tests/expectations/tests/use-core.rs @@ -51,7 +51,7 @@ impl Default for _bindgen_ty_1 { } } } -extern "C" { +unsafe extern "C" { pub static mut bazz: _bindgen_ty_1; } pub type fooFunction = ::core::option::Option< diff --git a/bindgen-tests/tests/expectations/tests/use-core_1_0.rs b/bindgen-tests/tests/expectations/tests/use-core_1_0.rs deleted file mode 100644 index 707ca3d962..0000000000 --- a/bindgen-tests/tests/expectations/tests/use-core_1_0.rs +++ /dev/null @@ -1,127 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern crate core; -#[repr(C)] -pub struct __BindgenUnionField(::core::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::core::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - ::core::mem::transmute(self) - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - ::core::mem::transmute(self) - } -} -impl ::core::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::core::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::core::marker::Copy for __BindgenUnionField {} -impl ::core::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::core::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::core::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::core::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Copy, Hash, PartialEq, Eq)] -pub struct foo { - pub a: ::std::os::raw::c_int, - pub b: ::std::os::raw::c_int, - pub bar: *mut ::std::os::raw::c_void, -} -#[test] -fn bindgen_test_layout_foo() { - const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::core::mem::size_of::(), 16usize, "Size of foo"); - assert_eq!(::core::mem::align_of::(), 8usize, "Alignment of foo"); - assert_eq!( - unsafe { ::core::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, - 0usize, - "Offset of field: foo::a", - ); - assert_eq!( - unsafe { ::core::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, - 4usize, - "Offset of field: foo::b", - ); - assert_eq!( - unsafe { ::core::ptr::addr_of!((*ptr).bar) as usize - ptr as usize }, - 8usize, - "Offset of field: foo::bar", - ); -} -impl Clone for foo { - fn clone(&self) -> Self { - *self - } -} -impl Default for foo { - fn default() -> Self { - unsafe { - let mut s: Self = ::core::mem::uninitialized(); - ::core::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)] -pub struct _bindgen_ty_1 { - pub bar: __BindgenUnionField<::std::os::raw::c_int>, - pub baz: __BindgenUnionField<::std::os::raw::c_long>, - pub bindgen_union_field: u64, -} -#[test] -fn bindgen_test_layout__bindgen_ty_1() { - const UNINIT: ::core::mem::MaybeUninit<_bindgen_ty_1> = ::core::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::core::mem::size_of::<_bindgen_ty_1>(), 8usize, "Size of _bindgen_ty_1"); - assert_eq!( - ::core::mem::align_of::<_bindgen_ty_1>(), - 8usize, - "Alignment of _bindgen_ty_1", - ); - assert_eq!( - unsafe { ::core::ptr::addr_of!((*ptr).bar) as usize - ptr as usize }, - 0usize, - "Offset of field: _bindgen_ty_1::bar", - ); - assert_eq!( - unsafe { ::core::ptr::addr_of!((*ptr).baz) as usize - ptr as usize }, - 0usize, - "Offset of field: _bindgen_ty_1::baz", - ); -} -impl Clone for _bindgen_ty_1 { - fn clone(&self) -> Self { - *self - } -} -extern "C" { - pub static mut bazz: _bindgen_ty_1; -} -pub type fooFunction = ::core::option::Option< - unsafe extern "C" fn(bar: ::std::os::raw::c_int), ->; diff --git a/bindgen-tests/tests/expectations/tests/va_list_aarch64_linux.rs b/bindgen-tests/tests/expectations/tests/va_list_aarch64_linux.rs new file mode 100644 index 0000000000..b33f4894c1 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/va_list_aarch64_linux.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] +#[repr(C, align(8))] +pub struct __BindgenOpaqueArray8(pub T); +impl Default for __BindgenOpaqueArray8<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } +} +pub type va_list = __BindgenOpaqueArray8<[u8; 32usize]>; +unsafe extern "C" { + pub fn vprintf( + format: *const ::std::os::raw::c_char, + vlist: __BindgenOpaqueArray8<[u8; 32usize]>, + ) -> ::std::os::raw::c_int; +} diff --git a/bindgen-tests/tests/expectations/tests/var-tracing.rs b/bindgen-tests/tests/expectations/tests/var-tracing.rs index 606cdd70b8..76ce0c50d6 100644 --- a/bindgen-tests/tests/expectations/tests/var-tracing.rs +++ b/bindgen-tests/tests/expectations/tests/var-tracing.rs @@ -10,7 +10,7 @@ const _: () = { ["Alignment of Bar"][::std::mem::align_of::() - 4usize]; ["Offset of field: Bar::m_baz"][::std::mem::offset_of!(Bar, m_baz) - 0usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3BarC1Ei"] pub fn Bar_Bar(this: *mut Bar, baz: ::std::os::raw::c_int); } @@ -27,7 +27,7 @@ impl Bar { pub struct Baz { pub _address: u8, } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Baz3FOOE"] pub static Baz_FOO: [Bar; 0usize]; } diff --git a/bindgen-tests/tests/expectations/tests/variadic-method.rs b/bindgen-tests/tests/expectations/tests/variadic-method.rs index 93ce01b813..deac5f719e 100644 --- a/bindgen-tests/tests/expectations/tests/variadic-method.rs +++ b/bindgen-tests/tests/expectations/tests/variadic-method.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z3fooPKcz"] pub fn foo(fmt: *const ::std::os::raw::c_char, ...); } @@ -13,7 +13,7 @@ const _: () = { ["Size of Bar"][::std::mem::size_of::() - 1usize]; ["Alignment of Bar"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3Bar3fooEPKcz"] pub fn Bar_foo(this: *mut Bar, fmt: *const ::std::os::raw::c_char, ...); } diff --git a/bindgen-tests/tests/expectations/tests/variadic-union.rs b/bindgen-tests/tests/expectations/tests/variadic-union.rs new file mode 100644 index 0000000000..471c9e7075 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/variadic-union.rs @@ -0,0 +1,14 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub union _Variadic_union { + pub _address: u8, +} +impl Default for _Variadic_union { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/vector.rs b/bindgen-tests/tests/expectations/tests/vector.rs index 2278b520d9..da53b4a8eb 100644 --- a/bindgen-tests/tests/expectations/tests/vector.rs +++ b/bindgen-tests/tests/expectations/tests/vector.rs @@ -13,7 +13,7 @@ const _: () = { pub type __m128 = [f32; 4usize]; pub type __m128d = [f64; 2usize]; pub type __m128i = [::std::os::raw::c_longlong; 2usize]; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_Z3fooDv2_xDv2_d"] pub fn foo(arg1: __m128i, arg2: __m128d) -> __m128; } diff --git a/bindgen-tests/tests/expectations/tests/virtual_dtor.rs b/bindgen-tests/tests/expectations/tests/virtual_dtor.rs index 84211429b1..d42be25202 100644 --- a/bindgen-tests/tests/expectations/tests/virtual_dtor.rs +++ b/bindgen-tests/tests/expectations/tests/virtual_dtor.rs @@ -20,7 +20,7 @@ impl Default for nsSlots { } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN7nsSlotsD1Ev"] pub fn nsSlots_nsSlots_destructor(this: *mut nsSlots); } diff --git a/bindgen-tests/tests/expectations/tests/virtual_overloaded.rs b/bindgen-tests/tests/expectations/tests/virtual_overloaded.rs index 800ebbef8f..4c3702faeb 100644 --- a/bindgen-tests/tests/expectations/tests/virtual_overloaded.rs +++ b/bindgen-tests/tests/expectations/tests/virtual_overloaded.rs @@ -23,11 +23,11 @@ impl Default for C { } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1C8do_thingEc"] pub fn C_do_thing(this: *mut ::std::os::raw::c_void, arg1: ::std::os::raw::c_char); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN1C8do_thingEi"] pub fn C_do_thing1(this: *mut ::std::os::raw::c_void, arg1: ::std::os::raw::c_int); } diff --git a/bindgen-tests/tests/expectations/tests/void_typedef.rs b/bindgen-tests/tests/expectations/tests/void_typedef.rs index 6c3b45dcc7..4997d49086 100644 --- a/bindgen-tests/tests/expectations/tests/void_typedef.rs +++ b/bindgen-tests/tests/expectations/tests/void_typedef.rs @@ -1,12 +1,12 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] pub type VOID = ::std::os::raw::c_void; pub type ALSO_VOID = VOID; -extern "C" { +unsafe extern "C" { pub fn this_api_returns_nothing(); } -extern "C" { +unsafe extern "C" { pub fn this_api_also_returns_nothing(); } -extern "C" { +unsafe extern "C" { pub fn this_other_api_also_returns_nothing(); } diff --git a/bindgen-tests/tests/expectations/tests/vtable_recursive_sig.rs b/bindgen-tests/tests/expectations/tests/vtable_recursive_sig.rs index fe08228ab9..9b9c2467aa 100644 --- a/bindgen-tests/tests/expectations/tests/vtable_recursive_sig.rs +++ b/bindgen-tests/tests/expectations/tests/vtable_recursive_sig.rs @@ -22,7 +22,7 @@ impl Default for Base { } } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN4Base9AsDerivedEv"] pub fn Base_AsDerived(this: *mut ::std::os::raw::c_void) -> *mut Derived; } diff --git a/bindgen-tests/tests/expectations/tests/wasm-constructor-returns.rs b/bindgen-tests/tests/expectations/tests/wasm-constructor-returns.rs index 092d592e29..ee26600a6b 100644 --- a/bindgen-tests/tests/expectations/tests/wasm-constructor-returns.rs +++ b/bindgen-tests/tests/expectations/tests/wasm-constructor-returns.rs @@ -9,7 +9,7 @@ const _: () = { ["Size of Foo"][::std::mem::size_of::() - 1usize]; ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; }; -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN3FooC1Ei"] pub fn Foo_Foo( this: *mut Foo, diff --git a/bindgen-tests/tests/expectations/tests/wasm-import-module.rs b/bindgen-tests/tests/expectations/tests/wasm-import-module.rs index 9725195e0e..aeeb17f1c1 100644 --- a/bindgen-tests/tests/expectations/tests/wasm-import-module.rs +++ b/bindgen-tests/tests/expectations/tests/wasm-import-module.rs @@ -1,5 +1,5 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #[link(wasm_import_module = "test-module")] -extern "C" { +unsafe extern "C" { pub fn test_function(); } diff --git a/bindgen-tests/tests/expectations/tests/weird_bitfields.rs b/bindgen-tests/tests/expectations/tests/weird_bitfields.rs index f76189eb74..ca8d84520b 100644 --- a/bindgen-tests/tests/expectations/tests/weird_bitfields.rs +++ b/bindgen-tests/tests/expectations/tests/weird_bitfields.rs @@ -15,10 +15,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -28,21 +25,48 @@ where byte & mask == mask } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { index % 8 }; let mask = 1 << bit_index; - if val { - *byte |= mask; - } else { - *byte &= !mask; - } + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; } #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { @@ -65,6 +89,26 @@ where val } #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); @@ -82,6 +126,24 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } } #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] @@ -94,7 +156,6 @@ pub enum nsStyleSVGOpacitySource { #[derive(Debug, Copy, Clone)] pub struct Weird { pub mStrokeDasharrayLength: ::std::os::raw::c_uint, - pub _bitfield_align_1: [u16; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, pub mClipRule: ::std::os::raw::c_uchar, pub mColorInterpolation: ::std::os::raw::c_uchar, @@ -107,7 +168,6 @@ pub struct Weird { pub mStrokeLinejoin: ::std::os::raw::c_uchar, pub mTextAnchor: ::std::os::raw::c_uchar, pub mTextRendering: ::std::os::raw::c_uchar, - pub _bitfield_align_2: [u8; 0], pub _bitfield_2: __BindgenBitfieldUnit<[u8; 2usize]>, pub __bindgen_padding_0: [u8; 3usize], } @@ -174,6 +234,31 @@ impl Weird { } } #[inline] + pub unsafe fn bitTest_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 16u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bitTest_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 16u8, + val as u64, + ) + } + } + #[inline] pub fn bitTest2(&self) -> ::std::os::raw::c_uint { unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 15u8) as u32) } } @@ -185,6 +270,31 @@ impl Weird { } } #[inline] + pub unsafe fn bitTest2_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 16usize, 15u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_bitTest2_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 4usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 16usize, + 15u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_1( bitTest: ::std::os::raw::c_uint, bitTest2: ::std::os::raw::c_uint, @@ -222,6 +332,34 @@ impl Weird { } } #[inline] + pub unsafe fn mFillOpacitySource_raw(this: *const Self) -> nsStyleSVGOpacitySource { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 0usize, 3u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_mFillOpacitySource_raw( + this: *mut Self, + val: nsStyleSVGOpacitySource, + ) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 0usize, + 3u8, + val as u64, + ) + } + } + #[inline] pub fn mStrokeOpacitySource(&self) -> nsStyleSVGOpacitySource { unsafe { ::std::mem::transmute(self._bitfield_2.get(3usize, 3u8) as u32) } } @@ -233,6 +371,36 @@ impl Weird { } } #[inline] + pub unsafe fn mStrokeOpacitySource_raw( + this: *const Self, + ) -> nsStyleSVGOpacitySource { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 3usize, 3u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_mStrokeOpacitySource_raw( + this: *mut Self, + val: nsStyleSVGOpacitySource, + ) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 3usize, + 3u8, + val as u64, + ) + } + } + #[inline] pub fn mStrokeDasharrayFromObject(&self) -> bool { unsafe { ::std::mem::transmute(self._bitfield_2.get(6usize, 1u8) as u8) } } @@ -244,6 +412,30 @@ impl Weird { } } #[inline] + pub unsafe fn mStrokeDasharrayFromObject_raw(this: *const Self) -> bool { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 6usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_mStrokeDasharrayFromObject_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 6usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn mStrokeDashoffsetFromObject(&self) -> bool { unsafe { ::std::mem::transmute(self._bitfield_2.get(7usize, 1u8) as u8) } } @@ -255,6 +447,30 @@ impl Weird { } } #[inline] + pub unsafe fn mStrokeDashoffsetFromObject_raw(this: *const Self) -> bool { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 7usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_mStrokeDashoffsetFromObject_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 7usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn mStrokeWidthFromObject(&self) -> bool { unsafe { ::std::mem::transmute(self._bitfield_2.get(8usize, 1u8) as u8) } } @@ -266,6 +482,30 @@ impl Weird { } } #[inline] + pub unsafe fn mStrokeWidthFromObject_raw(this: *const Self) -> bool { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 8usize, 1u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_mStrokeWidthFromObject_raw(this: *mut Self, val: bool) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 2usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 8usize, + 1u8, + val as u64, + ) + } + } + #[inline] pub fn new_bitfield_2( mFillOpacitySource: nsStyleSVGOpacitySource, mStrokeOpacitySource: nsStyleSVGOpacitySource, diff --git a/bindgen-tests/tests/expectations/tests/win32-dtors.rs b/bindgen-tests/tests/expectations/tests/win32-dtors.rs index 042aa8cece..d7ed1290f8 100644 --- a/bindgen-tests/tests/expectations/tests/win32-dtors.rs +++ b/bindgen-tests/tests/expectations/tests/win32-dtors.rs @@ -4,32 +4,26 @@ pub struct CppObj { pub x: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_CppObj() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 4usize, "Size of CppObj"); - assert_eq!(::std::mem::align_of::(), 4usize, "Alignment of CppObj"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, - 0usize, - "Offset of field: CppObj::x", - ); -} -extern "C" { +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of CppObj"][::std::mem::size_of::() - 4usize]; + ["Alignment of CppObj"][::std::mem::align_of::() - 4usize]; + ["Offset of field: CppObj::x"][::std::mem::offset_of!(CppObj, x) - 0usize]; +}; +unsafe extern "C" { #[link_name = "\u{1}??0CppObj@@QEAA@H@Z"] pub fn CppObj_CppObj(this: *mut CppObj, x: ::std::os::raw::c_int); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}??1CppObj@@QEAA@XZ"] pub fn CppObj_CppObj_destructor(this: *mut CppObj); } impl CppObj { #[inline] pub unsafe fn new(x: ::std::os::raw::c_int) -> Self { - let mut __bindgen_tmp = ::std::mem::uninitialized(); - CppObj_CppObj(&mut __bindgen_tmp, x); - __bindgen_tmp + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + CppObj_CppObj(__bindgen_tmp.as_mut_ptr(), x); + __bindgen_tmp.assume_init() } #[inline] pub unsafe fn destruct(&mut self) { @@ -44,40 +38,34 @@ pub struct CppObj2 { pub vtable_: *const CppObj2__bindgen_vtable, pub x: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_CppObj2() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 16usize, "Size of CppObj2"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of CppObj2"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, - 8usize, - "Offset of field: CppObj2::x", - ); -} -extern "C" { +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of CppObj2"][::std::mem::size_of::() - 16usize]; + ["Alignment of CppObj2"][::std::mem::align_of::() - 8usize]; + ["Offset of field: CppObj2::x"][::std::mem::offset_of!(CppObj2, x) - 8usize]; +}; +unsafe extern "C" { #[link_name = "\u{1}??0CppObj2@@QEAA@H@Z"] pub fn CppObj2_CppObj2(this: *mut CppObj2, x: ::std::os::raw::c_int); } impl Default for CppObj2 { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } impl CppObj2 { #[inline] pub unsafe fn new(x: ::std::os::raw::c_int) -> Self { - let mut __bindgen_tmp = ::std::mem::uninitialized(); - CppObj2_CppObj2(&mut __bindgen_tmp, x); - __bindgen_tmp + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + CppObj2_CppObj2(__bindgen_tmp.as_mut_ptr(), x); + __bindgen_tmp.assume_init() } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}??1CppObj2@@UEAA@XZ"] pub fn CppObj2_CppObj2_destructor(this: *mut CppObj2); } @@ -87,40 +75,34 @@ pub struct CppObj3 { pub _base: CppObj2, pub x: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_CppObj3() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 24usize, "Size of CppObj3"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of CppObj3"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, - 16usize, - "Offset of field: CppObj3::x", - ); -} -extern "C" { +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of CppObj3"][::std::mem::size_of::() - 24usize]; + ["Alignment of CppObj3"][::std::mem::align_of::() - 8usize]; + ["Offset of field: CppObj3::x"][::std::mem::offset_of!(CppObj3, x) - 16usize]; +}; +unsafe extern "C" { #[link_name = "\u{1}??0CppObj3@@QEAA@H@Z"] pub fn CppObj3_CppObj3(this: *mut CppObj3, x: ::std::os::raw::c_int); } impl Default for CppObj3 { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } impl CppObj3 { #[inline] pub unsafe fn new(x: ::std::os::raw::c_int) -> Self { - let mut __bindgen_tmp = ::std::mem::uninitialized(); - CppObj3_CppObj3(&mut __bindgen_tmp, x); - __bindgen_tmp + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + CppObj3_CppObj3(__bindgen_tmp.as_mut_ptr(), x); + __bindgen_tmp.assume_init() } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}??1CppObj3@@UEAA@XZ"] pub fn CppObj3_CppObj3_destructor(this: *mut CppObj3); } @@ -130,40 +112,34 @@ pub struct CppObj4 { pub _base: CppObj2, pub x: ::std::os::raw::c_int, } -#[test] -fn bindgen_test_layout_CppObj4() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!(::std::mem::size_of::(), 24usize, "Size of CppObj4"); - assert_eq!(::std::mem::align_of::(), 8usize, "Alignment of CppObj4"); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, - 16usize, - "Offset of field: CppObj4::x", - ); -} -extern "C" { +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of CppObj4"][::std::mem::size_of::() - 24usize]; + ["Alignment of CppObj4"][::std::mem::align_of::() - 8usize]; + ["Offset of field: CppObj4::x"][::std::mem::offset_of!(CppObj4, x) - 16usize]; +}; +unsafe extern "C" { #[link_name = "\u{1}??0CppObj4@@QEAA@H@Z"] pub fn CppObj4_CppObj4(this: *mut CppObj4, x: ::std::os::raw::c_int); } impl Default for CppObj4 { fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } } } impl CppObj4 { #[inline] pub unsafe fn new(x: ::std::os::raw::c_int) -> Self { - let mut __bindgen_tmp = ::std::mem::uninitialized(); - CppObj4_CppObj4(&mut __bindgen_tmp, x); - __bindgen_tmp + let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); + CppObj4_CppObj4(__bindgen_tmp.as_mut_ptr(), x); + __bindgen_tmp.assume_init() } } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}??1CppObj4@@UEAA@XZ"] pub fn CppObj4_CppObj4_destructor(this: *mut CppObj4); } diff --git a/bindgen-tests/tests/expectations/tests/win32-thiscall.rs b/bindgen-tests/tests/expectations/tests/win32-thiscall.rs new file mode 100644 index 0000000000..aecdfbbf1f --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/win32-thiscall.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#![cfg(not(test))] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo { + pub _address: u8, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of Foo"][::std::mem::size_of::() - 1usize]; + ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; +}; +unsafe extern "thiscall" { + #[link_name = "\u{1}?test@Foo@@QAEXXZ"] + pub fn Foo_test(this: *mut Foo); +} +unsafe extern "thiscall" { + #[link_name = "\u{1}?test2@Foo@@QAEHH@Z"] + pub fn Foo_test2( + this: *mut Foo, + var: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +impl Foo { + #[inline] + pub unsafe fn test(&mut self) { + Foo_test(self) + } + #[inline] + pub unsafe fn test2(&mut self, var: ::std::os::raw::c_int) -> ::std::os::raw::c_int { + Foo_test2(self, var) + } +} diff --git a/bindgen-tests/tests/expectations/tests/win32-thiscall_1_0.rs b/bindgen-tests/tests/expectations/tests/win32-thiscall_1_0.rs deleted file mode 100644 index 185b935808..0000000000 --- a/bindgen-tests/tests/expectations/tests/win32-thiscall_1_0.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -#[derive(Debug, Default, Copy)] -pub struct Foo { - pub _address: u8, -} -#[test] -fn bindgen_test_layout_Foo() { - assert_eq!(::std::mem::size_of::(), 1usize, "Size of Foo"); - assert_eq!(::std::mem::align_of::(), 1usize, "Alignment of Foo"); -} -impl Clone for Foo { - fn clone(&self) -> Self { - *self - } -} diff --git a/bindgen-tests/tests/expectations/tests/win32-thiscall_nightly.rs b/bindgen-tests/tests/expectations/tests/win32-thiscall_nightly.rs index 3c84de7b95..87b63574a9 100644 --- a/bindgen-tests/tests/expectations/tests/win32-thiscall_nightly.rs +++ b/bindgen-tests/tests/expectations/tests/win32-thiscall_nightly.rs @@ -11,11 +11,11 @@ const _: () = { ["Size of Foo"][::std::mem::size_of::() - 1usize]; ["Alignment of Foo"][::std::mem::align_of::() - 1usize]; }; -extern "thiscall" { +unsafe extern "thiscall" { #[link_name = "\u{1}?test@Foo@@QAEXXZ"] pub fn Foo_test(this: *mut Foo); } -extern "thiscall" { +unsafe extern "thiscall" { #[link_name = "\u{1}?test2@Foo@@QAEHH@Z"] pub fn Foo_test2( this: *mut Foo, diff --git a/bindgen-tests/tests/expectations/tests/win32-vectorcall-nightly.rs b/bindgen-tests/tests/expectations/tests/win32-vectorcall-nightly.rs index a262b78c59..1c7b2fdbf6 100644 --- a/bindgen-tests/tests/expectations/tests/win32-vectorcall-nightly.rs +++ b/bindgen-tests/tests/expectations/tests/win32-vectorcall-nightly.rs @@ -1,7 +1,7 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] #![cfg(feature = "nightly")] #![feature(abi_vectorcall)] -extern "vectorcall" { +unsafe extern "vectorcall" { #[link_name = "\u{1}test_vectorcall@@16"] pub fn test_vectorcall( a: ::std::os::raw::c_int, diff --git a/bindgen-tests/tests/expectations/tests/win32-vectorcall-1_0.rs b/bindgen-tests/tests/expectations/tests/win32-vectorcall.rs similarity index 100% rename from bindgen-tests/tests/expectations/tests/win32-vectorcall-1_0.rs rename to bindgen-tests/tests/expectations/tests/win32-vectorcall.rs diff --git a/bindgen-tests/tests/expectations/tests/with_array_pointers_arguments.rs b/bindgen-tests/tests/expectations/tests/with_array_pointers_arguments.rs index cc82fd4daf..7cc1d65daf 100644 --- a/bindgen-tests/tests/expectations/tests/with_array_pointers_arguments.rs +++ b/bindgen-tests/tests/expectations/tests/with_array_pointers_arguments.rs @@ -1,11 +1,11 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn test_fn( a: f32, arr: *mut [::std::os::raw::c_int; 20usize], ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn test_fn2( arr: *const [f32; 20usize], b: ::std::os::raw::c_int, @@ -13,6 +13,6 @@ extern "C" { } pub type defArr = [::std::os::raw::c_char; 20usize]; pub type foo = ::std::option::Option; -extern "C" { +unsafe extern "C" { pub fn bar(a: *mut defArr); } diff --git a/bindgen-tests/tests/expectations/tests/without_array_pointers_arguments.rs b/bindgen-tests/tests/expectations/tests/without_array_pointers_arguments.rs index f48e5f7f5c..d642e84d27 100644 --- a/bindgen-tests/tests/expectations/tests/without_array_pointers_arguments.rs +++ b/bindgen-tests/tests/expectations/tests/without_array_pointers_arguments.rs @@ -1,14 +1,14 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { pub fn test_fn(a: f32, arr: *mut ::std::os::raw::c_int) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn test_fn2(arr: *const f32, b: ::std::os::raw::c_int) -> ::std::os::raw::c_int; } pub type defArr = [::std::os::raw::c_char; 20usize]; pub type foo = ::std::option::Option< unsafe extern "C" fn(a: *mut ::std::os::raw::c_char), >; -extern "C" { +unsafe extern "C" { pub fn bar(a: *mut ::std::os::raw::c_char); } diff --git a/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs b/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs index 46b369b2f4..bafcad8a7e 100644 --- a/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs +++ b/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs @@ -1,17 +1,17 @@ #![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -extern "C" { +unsafe extern "C" { #[link_name = "foo__extern"] pub fn foo() -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "bar__extern"] pub fn bar() -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "takes_ptr__extern"] pub fn takes_ptr(arg: *mut ::std::os::raw::c_int) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "takes_fn_ptr__extern"] pub fn takes_fn_ptr( f: ::std::option::Option< @@ -19,7 +19,7 @@ extern "C" { >, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "takes_fn__extern"] pub fn takes_fn( f: ::std::option::Option< @@ -30,11 +30,11 @@ extern "C" { pub type func = ::std::option::Option< unsafe extern "C" fn(arg1: ::std::os::raw::c_int) -> ::std::os::raw::c_int, >; -extern "C" { +unsafe extern "C" { #[link_name = "takes_alias__extern"] pub fn takes_alias(f: func) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "takes_qualified__extern"] pub fn takes_qualified( arg: *const *const ::std::os::raw::c_int, @@ -42,25 +42,25 @@ extern "C" { } pub const foo_BAR: foo = 0; pub type foo = ::std::os::raw::c_uint; -extern "C" { +unsafe extern "C" { #[link_name = "takes_enum__extern"] pub fn takes_enum(f: foo) -> foo; } -extern "C" { +unsafe extern "C" { #[link_name = "nevermore__extern"] pub fn nevermore(); } -extern "C" { +unsafe extern "C" { #[link_name = "takes_fn_with_no_args__extern"] pub fn takes_fn_with_no_args( f: ::std::option::Option ::std::os::raw::c_int>, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "no_extra_argument__extern"] pub fn no_extra_argument(va: *mut __va_list_tag); } -extern "C" { +unsafe extern "C" { #[link_name = "many_va_list__extern"] pub fn many_va_list( i: ::std::os::raw::c_int, @@ -68,14 +68,14 @@ extern "C" { va2: *mut __va_list_tag, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "wrap_as_variadic_fn1__extern"] pub fn wrap_as_variadic_fn1_wrapped( i: ::std::os::raw::c_int, ... ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { #[link_name = "wrap_as_variadic_fn2__extern"] pub fn wrap_as_variadic_fn2_wrapped(i: ::std::os::raw::c_int, ...); } diff --git a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_anon_union.rs b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_anon_union.rs new file mode 100644 index 0000000000..94bddf4c25 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_anon_union.rs @@ -0,0 +1,57 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +pub struct TErrorResult { + pub mResult: ::std::os::raw::c_int, + pub __bindgen_anon_1: TErrorResult__bindgen_ty_1, + pub mMightHaveUnreported: bool, + pub mUnionState: TErrorResult_UnionState, +} +pub const TErrorResult_UnionState_HasMessage: TErrorResult_UnionState = 0; +pub const TErrorResult_UnionState_HasException: TErrorResult_UnionState = 0; +pub type TErrorResult_UnionState = i32; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct TErrorResult_Message { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct TErrorResult_DOMExceptionInfo { + _unused: [u8; 0], +} +#[repr(C)] +pub union TErrorResult__bindgen_ty_1 { + pub mMessage: *mut TErrorResult_Message, + pub mDOMExceptionInfo: *mut TErrorResult_DOMExceptionInfo, +} +impl Default for TErrorResult__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl Default for TErrorResult { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +pub struct ErrorResult { + pub _base: TErrorResult, +} +impl Default for ErrorResult { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_anon_union_1_0.rs b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_anon_union_1_0.rs deleted file mode 100644 index dfe2213ed4..0000000000 --- a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_anon_union_1_0.rs +++ /dev/null @@ -1,100 +0,0 @@ -#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] -#[repr(C)] -pub struct __BindgenUnionField(::std::marker::PhantomData); -impl __BindgenUnionField { - #[inline] - pub fn new() -> Self { - __BindgenUnionField(::std::marker::PhantomData) - } - #[inline] - pub unsafe fn as_ref(&self) -> &T { - unsafe { ::std::mem::transmute(self) } - } - #[inline] - pub unsafe fn as_mut(&mut self) -> &mut T { - unsafe { ::std::mem::transmute(self) } - } -} -impl ::std::default::Default for __BindgenUnionField { - #[inline] - fn default() -> Self { - Self::new() - } -} -impl ::std::clone::Clone for __BindgenUnionField { - #[inline] - fn clone(&self) -> Self { - *self - } -} -impl ::std::marker::Copy for __BindgenUnionField {} -impl ::std::fmt::Debug for __BindgenUnionField { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - fmt.write_str("__BindgenUnionField") - } -} -impl ::std::hash::Hash for __BindgenUnionField { - fn hash(&self, _state: &mut H) {} -} -impl ::std::cmp::PartialEq for __BindgenUnionField { - fn eq(&self, _other: &__BindgenUnionField) -> bool { - true - } -} -impl ::std::cmp::Eq for __BindgenUnionField {} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct TErrorResult { - pub mResult: ::std::os::raw::c_int, - pub __bindgen_anon_1: TErrorResult__bindgen_ty_1, - pub mMightHaveUnreported: bool, - pub mUnionState: TErrorResult_UnionState, -} -pub const TErrorResult_UnionState_HasMessage: TErrorResult_UnionState = 0; -pub const TErrorResult_UnionState_HasException: TErrorResult_UnionState = 0; -pub type TErrorResult_UnionState = i32; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct TErrorResult_Message { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct TErrorResult_DOMExceptionInfo { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct TErrorResult__bindgen_ty_1 { - pub mMessage: __BindgenUnionField<*mut TErrorResult_Message>, - pub mDOMExceptionInfo: __BindgenUnionField<*mut TErrorResult_DOMExceptionInfo>, - pub bindgen_union_field: u64, -} -impl Default for TErrorResult { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} -#[repr(C)] -#[derive(Debug, Copy)] -pub struct ErrorResult { - pub _base: TErrorResult, -} -impl Clone for ErrorResult { - fn clone(&self) -> Self { - *self - } -} -impl Default for ErrorResult { - fn default() -> Self { - unsafe { - let mut s: Self = ::std::mem::uninitialized(); - ::std::ptr::write_bytes(&mut s, 0, 1); - s - } - } -} diff --git a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_class.rs b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_class.rs index 5f64396f6b..617a037631 100644 --- a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_class.rs +++ b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_class.rs @@ -166,26 +166,26 @@ impl Default for WithUnion { pub struct RealAbstractionWithTonsOfMethods { pub _address: u8, } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZNK32RealAbstractionWithTonsOfMethods3barEv"] pub fn RealAbstractionWithTonsOfMethods_bar( this: *const RealAbstractionWithTonsOfMethods, ); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3barEv"] pub fn RealAbstractionWithTonsOfMethods_bar1( this: *mut RealAbstractionWithTonsOfMethods, ); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3barEi"] pub fn RealAbstractionWithTonsOfMethods_bar2( this: *mut RealAbstractionWithTonsOfMethods, foo: ::std::os::raw::c_int, ); } -extern "C" { +unsafe extern "C" { #[link_name = "\u{1}_ZN32RealAbstractionWithTonsOfMethods3staEv"] pub fn RealAbstractionWithTonsOfMethods_sta(); } diff --git a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs index 2f5b4cc5ba..05be5d9944 100644 --- a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs +++ b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs @@ -16,13 +16,14 @@ pub struct TestLib { unsafe extern "C" fn() -> ::std::os::raw::c_int, ::libloading::Error, >, + pub FLUX: Result<*mut ::std::os::raw::c_int, ::libloading::Error>, } impl TestLib { pub unsafe fn new
-- ...", trailing_var_arg = true )] +#[allow(clippy::doc_markdown)] struct BindgenCommand { /// C or C++ header file. header: Option, @@ -246,6 +258,9 @@ struct BindgenCommand { /// Use extern crate instead of use for objc. #[arg(long)] objc_extern_crate: bool, + /// Use `NonNull` in place of raw pointers for C++ references. + #[arg(long)] + nonnull_references: bool, /// Generate block signatures instead of void pointers. #[arg(long)] generate_block: bool, @@ -265,8 +280,8 @@ struct BindgenCommand { #[arg(long, value_name = "PREFIX")] ctypes_prefix: Option, /// Use the given PREFIX for anonymous fields. - #[arg(long, default_value = DEFAULT_ANON_FIELDS_PREFIX, value_name = "PREFIX")] - anon_fields_prefix: String, + #[arg(long, value_name = "PREFIX")] + anon_fields_prefix: Option, /// Time the different bindgen phases and print to stderr #[arg(long)] time_phases: bool, @@ -329,6 +344,8 @@ struct BindgenCommand { module_raw_line: Vec, #[arg(long, help = rust_target_help())] rust_target: Option, + #[arg(long, value_name = "EDITION", help = rust_edition_help())] + rust_edition: Option, /// Use types from Rust core instead of std. #[arg(long)] use_core: bool, @@ -406,6 +423,9 @@ struct BindgenCommand { /// The NAME to be used in a #[link(wasm_import_module = ...)] statement #[arg(long, value_name = "NAME")] wasm_import_module_name: Option, + /// Attributes to apply to the extern function block. + #[arg(long, value_name = "ATTRS")] + extern_fn_block_attrs: Vec, /// Use dynamic loading mode with the given library NAME. #[arg(long, value_name = "NAME")] dynamic_loading: Option, @@ -427,6 +447,15 @@ struct BindgenCommand { /// Always output explicit padding fields. #[arg(long)] explicit_padding: bool, + /// Always be specific about the 'receiver' of a virtual function. + #[arg(long)] + use_specific_virtual_function_receiver: bool, + /// Use distinct char16_t + #[arg(long)] + use_distinct_char16_t: bool, + /// Output C++ overloaded operators + #[arg(long)] + represent_cxx_operators: bool, /// Enables generation of vtable functions. #[arg(long)] vtable_generation: bool, @@ -451,46 +480,59 @@ struct BindgenCommand { /// Use DSTs to represent structures with flexible array members. #[arg(long)] flexarray_dst: bool, - /// Derive custom traits on any kind of type. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a coma-separated list of derive macros. + /// Derive custom traits on any kind of type. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a comma-separated list of derive macros. #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)] with_derive_custom: Vec<(Vec, String)>, - /// Derive custom traits on a `struct`. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a coma-separated list of derive macros. + /// Derive custom traits on a `struct`. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a comma-separated list of derive macros. #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)] with_derive_custom_struct: Vec<(Vec, String)>, - /// Derive custom traits on an `enum. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a coma-separated list of derive macros. + /// Derive custom traits on an `enum`. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a comma-separated list of derive macros. #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)] with_derive_custom_enum: Vec<(Vec, String)>, - /// Derive custom traits on a `union`. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a coma-separated list of derive macros. + /// Derive custom traits on a `union`. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a comma-separated list of derive macros. #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)] with_derive_custom_union: Vec<(Vec, String)>, - /// Add custom attributes on any kind of type. The CUSTOM value must be of the shape REGEX=ATTRIBUTE where ATTRIBUTE is a coma-separated list of attributes. + /// Add custom attributes on any kind of type. The CUSTOM value must be of the shape REGEX=ATTRIBUTE where ATTRIBUTE is a comma-separated list of attributes. #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_attribute)] with_attribute_custom: Vec<(Vec, String)>, - /// Add custom attributes on a `struct`. The CUSTOM value must be of the shape REGEX=ATTRIBUTE where ATTRIBUTE is a coma-separated list of attributes. + /// Add custom attributes on a `struct`. The CUSTOM value must be of the shape REGEX=ATTRIBUTE where ATTRIBUTE is a comma-separated list of attributes. #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_attribute)] with_attribute_custom_struct: Vec<(Vec, String)>, - /// Add custom attributes on an `enum. The CUSTOM value must be of the shape REGEX=ATTRIBUTE where ATTRIBUTE is a coma-separated list of attributes. + /// Add custom attributes on an `enum`. The CUSTOM value must be of the shape REGEX=ATTRIBUTE where ATTRIBUTE is a comma-separated list of attributes. #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_attribute)] with_attribute_custom_enum: Vec<(Vec, String)>, - /// Add custom attributes on a `union`. The CUSTOM value must be of the shape REGEX=ATTRIBUTE where ATTRIBUTE is a coma-separated list of attributes. + /// Add custom attributes on a `union`. The CUSTOM value must be of the shape REGEX=ATTRIBUTE where ATTRIBUTE is a comma-separated list of attributes. #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_attribute)] with_attribute_custom_union: Vec<(Vec, String)>, /// Generate wrappers for `static` and `static inline` functions. - #[arg(long, requires = "experimental")] + #[arg(long)] wrap_static_fns: bool, /// Sets the PATH for the source file that must be created due to the presence of `static` and /// `static inline` functions. - #[arg(long, requires = "experimental", value_name = "PATH")] + #[arg(long, value_name = "PATH")] wrap_static_fns_path: Option, /// Sets the SUFFIX added to the extern wrapper functions generated for `static` and `static /// inline` functions. - #[arg(long, requires = "experimental", value_name = "SUFFIX")] + #[arg(long, value_name = "SUFFIX")] wrap_static_fns_suffix: Option, /// Set the default VISIBILITY of fields, including bitfields and accessor methods for /// bitfields. This flag is ignored if the `--respect-cxx-access-specs` flag is used. #[arg(long, value_name = "VISIBILITY")] default_visibility: Option, + /// Whether to generate C++ functions marked with "=delete" even though they + /// can't be called. + #[arg(long)] + generate_deleted_functions: bool, + /// Whether to generate C++ "pure virtual" functions even though they can't + /// be called. + #[arg(long)] + generate_pure_virtual_functions: bool, + /// Whether to generate C++ private functions even though they can't + /// be called. + #[arg(long)] + generate_private_functions: bool, /// Whether to emit diagnostics or not. + #[cfg(feature = "experimental")] #[arg(long, requires = "experimental")] emit_diagnostics: bool, /// Generates completions for the specified SHELL, sends them to `stdout` and exits. @@ -554,6 +596,7 @@ where no_doc_comments, no_recursive_allowlist, objc_extern_crate, + nonnull_references, generate_block, generate_cstr, block_extern_crate, @@ -582,6 +625,7 @@ where raw_line, module_raw_line, rust_target, + rust_edition, use_core, conservative_inline_namespaces, allowlist_function, @@ -606,6 +650,7 @@ where enable_function_attribute_detection, use_array_pointers_in_arguments, wasm_import_module_name, + extern_fn_block_attrs, dynamic_loading, dynamic_link_require_all, prefix_link_name, @@ -613,6 +658,9 @@ where translate_enum_integer_types, c_naming, explicit_padding, + use_specific_virtual_function_receiver, + use_distinct_char16_t, + represent_cxx_operators, vtable_generation, sort_semantically, merge_extern_blocks, @@ -633,6 +681,10 @@ where wrap_static_fns_path, wrap_static_fns_suffix, default_visibility, + generate_deleted_functions, + generate_pure_virtual_functions, + generate_private_functions, + #[cfg(feature = "experimental")] emit_diagnostics, generate_shell_completions, experimental: _, @@ -645,10 +697,10 @@ where shell, &mut BindgenCommand::command(), "bindgen", - &mut std::io::stdout(), + &mut io::stdout(), ); - exit(0); + exit(0) } if version { @@ -657,273 +709,280 @@ where option_env!("CARGO_PKG_VERSION").unwrap_or("unknown") ); if verbose { - println!("Clang: {}", bindgen::clang_version().full); + println!("Clang: {}", crate::clang_version().full); } - std::process::exit(0); - } - - let mut builder = builder(); - - if let Some(header) = header { - builder = builder.header(header); - } else { - return Err(io::Error::new(io::ErrorKind::Other, "Header not found")); - } - - if let Some(rust_target) = rust_target { - builder = builder.rust_target(rust_target); - } - - if let Some(variant) = default_enum_style { - builder = builder.default_enum_style(variant); - } - - for regex in bitfield_enum { - builder = builder.bitfield_enum(regex); - } - - for regex in newtype_enum { - builder = builder.newtype_enum(regex); - } - - for regex in newtype_global_enum { - builder = builder.newtype_global_enum(regex); - } - - for regex in rustified_enum { - builder = builder.rustified_enum(regex); - } - - for regex in rustified_non_exhaustive_enum { - builder = builder.rustified_non_exhaustive_enum(regex); - } - - for regex in constified_enum { - builder = builder.constified_enum(regex); - } - - for regex in constified_enum_module { - builder = builder.constified_enum_module(regex); - } - - if let Some(default_macro_constant_type) = default_macro_constant_type { - builder = - builder.default_macro_constant_type(default_macro_constant_type) - } - - if let Some(variant) = default_alias_style { - builder = builder.default_alias_style(variant); - } - - for regex in normal_alias { - builder = builder.type_alias(regex); - } - - for regex in new_type_alias { - builder = builder.new_type_alias(regex); - } - - for regex in new_type_alias_deref { - builder = builder.new_type_alias_deref(regex); - } - - if let Some(variant) = default_non_copy_union_style { - builder = builder.default_non_copy_union_style(variant); - } - - for regex in bindgen_wrapper_union { - builder = builder.bindgen_wrapper_union(regex); - } - - for regex in manually_drop_union { - builder = builder.manually_drop_union(regex); - } - - for ty in blocklist_type { - builder = builder.blocklist_type(ty); - } - - for fun in blocklist_function { - builder = builder.blocklist_function(fun); - } - - for id in blocklist_item { - builder = builder.blocklist_item(id); - } - - for file in blocklist_file { - builder = builder.blocklist_file(file); - } - - for var in blocklist_var { - builder = builder.blocklist_var(var); - } - - if builtins { - builder = builder.emit_builtins(); - } - - if no_layout_tests { - builder = builder.layout_tests(false); - } - - if no_derive_copy { - builder = builder.derive_copy(false); - } - - if no_derive_debug { - builder = builder.derive_debug(false); - } - - if impl_debug { - builder = builder.impl_debug(true); - } - - if impl_partialeq { - builder = builder.impl_partialeq(true); - } - - if with_derive_default { - builder = builder.derive_default(true); - } - - if with_derive_hash { - builder = builder.derive_hash(true); - } - - if with_derive_partialeq { - builder = builder.derive_partialeq(true); - } - - if with_derive_partialord { - builder = builder.derive_partialord(true); - } - - if with_derive_eq { - builder = builder.derive_eq(true); - } - - if with_derive_ord { - builder = builder.derive_ord(true); - } - - if no_derive_default { - builder = builder.derive_default(false); - } - - if no_prepend_enum_name { - builder = builder.prepend_enum_name(false); - } - - if no_include_path_detection { - builder = builder.detect_include_paths(false); - } - - if fit_macro_constant_types { - builder = builder.fit_macro_constants(true); - } - - if time_phases { - builder = builder.time_phases(true); - } - if use_array_pointers_in_arguments { - builder = builder.array_pointers_in_arguments(true); + exit(0) } - if let Some(wasm_import_name) = wasm_import_module_name { - builder = builder.wasm_import_module_name(wasm_import_name); - } - - if let Some(prefix) = ctypes_prefix { - builder = builder.ctypes_prefix(prefix); - } - - builder = builder.anon_fields_prefix(anon_fields_prefix); - - if let Some(config) = generate { - builder = builder.with_codegen_config(config); - } - - if emit_clang_ast { - builder = builder.emit_clang_ast(); + if header.is_none() { + return Err(io::Error::new(io::ErrorKind::Other, "Header not found")); } - if emit_ir { - builder = builder.emit_ir(); - } + let mut builder = builder(); - if let Some(path) = emit_ir_graphviz { - builder = builder.emit_ir_graphviz(path); + #[derive(Debug)] + struct PrefixLinkNameCallback { + prefix: String, } - if enable_cxx_namespaces { - builder = builder.enable_cxx_namespaces(); + impl ParseCallbacks for PrefixLinkNameCallback { + fn generated_link_name_override( + &self, + item_info: ItemInfo<'_>, + ) -> Option { + let mut prefix = self.prefix.clone(); + prefix.push_str(item_info.name); + Some(prefix) + } } - if enable_function_attribute_detection { - builder = builder.enable_function_attribute_detection(); + #[derive(Debug)] + struct CustomDeriveCallback { + derives: Vec, + kind: Option, + regex_set: RegexSet, } - if disable_name_namespacing { - builder = builder.disable_name_namespacing(); - } + impl ParseCallbacks for CustomDeriveCallback { + fn cli_args(&self) -> Vec { + let mut args = vec![]; - if disable_nested_struct_naming { - builder = builder.disable_nested_struct_naming(); - } + let flag = match &self.kind { + None => "--with-derive-custom", + Some(TypeKind::Struct) => "--with-derive-custom-struct", + Some(TypeKind::Enum) => "--with-derive-custom-enum", + Some(TypeKind::Union) => "--with-derive-custom-union", + }; - if disable_untagged_union { - builder = builder.disable_untagged_union(); - } + let derives = self.derives.join(","); - if disable_header_comment { - builder = builder.disable_header_comment(); - } + for item in self.regex_set.get_items() { + args.extend_from_slice(&[ + flag.to_owned(), + format!("{item}={derives}"), + ]); + } - if ignore_functions { - builder = builder.ignore_functions(); - } + args + } - if ignore_methods { - builder = builder.ignore_methods(); + fn add_derives(&self, info: &DeriveInfo<'_>) -> Vec { + if self.kind.map_or(true, |kind| kind == info.kind) && + self.regex_set.matches(info.name) + { + return self.derives.clone(); + } + vec![] + } } - if no_convert_floats { - builder = builder.no_convert_floats(); + #[derive(Debug)] + struct CustomAttributeCallback { + attributes: Vec, + kind: Option, + regex_set: RegexSet, } - if no_doc_comments { - builder = builder.generate_comments(false); - } + impl ParseCallbacks for CustomAttributeCallback { + fn cli_args(&self) -> Vec { + let mut args = vec![]; - if no_recursive_allowlist { - builder = builder.allowlist_recursively(false); - } + let flag = match &self.kind { + None => "--with-attribute-custom", + Some(TypeKind::Struct) => "--with-attribute-custom-struct", + Some(TypeKind::Enum) => "--with-attribute-custom-enum", + Some(TypeKind::Union) => "--with-attribute-custom-union", + }; - if objc_extern_crate { - builder = builder.objc_extern_crate(true); - } + let attributes = self.attributes.join(","); - if generate_block { - builder = builder.generate_block(true); - } + for item in self.regex_set.get_items() { + args.extend_from_slice(&[ + flag.to_owned(), + format!("{item}={attributes}"), + ]); + } - if generate_cstr { - builder = builder.generate_cstr(true); - } + args + } - if block_extern_crate { - builder = builder.block_extern_crate(true); + fn add_attributes(&self, info: &AttributeInfo<'_>) -> Vec { + if self.kind.map_or(true, |kind| kind == info.kind) && + self.regex_set.matches(info.name) + { + return self.attributes.clone(); + } + vec![] + } } - for ty in opaque_type { - builder = builder.opaque_type(ty); + /// Macro used to apply CLI arguments to a builder. + /// + /// This is done by passing an identifier for each argument and a function to be applied over + /// the builder. For example: + /// ```rust,ignore + /// fn apply_arg(builder: Builder, arg_value: Value) -> Builder { + /// todo!() + /// } + /// + /// apply_args!( + /// builder { + /// arg => apply_arg, + /// } + /// ); + /// ``` + /// + /// If the identifier of the argument is the same as an already existing builder method then + /// you can omit the second part: + /// ```rust,ignore + /// apply_args!( + /// builder { + /// arg + /// } + /// ); + /// ``` + /// Which expands to the same code as: + /// ```rust,ignore + /// apply_args!( + /// builder { + /// arg => Builder::arg, + /// } + /// ); + /// ``` + macro_rules! apply_args { + ($builder:ident {}) => { $builder }; + ($builder:ident {$arg:ident => $function:expr, $($token:tt)*}) => { + { + $builder = CliArg::apply($arg, $builder, $function); + apply_args!($builder {$($token)*}) + } + }; + ($builder:ident {$arg:ident, $($token:tt)*}) => { + { + $builder = CliArg::apply($arg, $builder, Builder::$arg); + apply_args!($builder {$($token)*}) + } + } } - for line in raw_line { - builder = builder.raw_line(line); - } + builder = apply_args!( + builder { + header, + rust_target, + rust_edition, + default_enum_style, + bitfield_enum, + newtype_enum, + newtype_global_enum, + rustified_enum, + rustified_non_exhaustive_enum, + constified_enum, + constified_enum_module, + default_macro_constant_type, + default_alias_style, + normal_alias => Builder::type_alias, + new_type_alias, + new_type_alias_deref, + default_non_copy_union_style, + bindgen_wrapper_union, + manually_drop_union, + blocklist_type, + blocklist_function, + blocklist_item, + blocklist_file, + blocklist_var, + builtins => |b, _| b.emit_builtins(), + no_layout_tests => |b, _| b.layout_tests(false), + no_derive_copy => |b, _| b.derive_copy(false), + no_derive_debug => |b, _| b.derive_debug(false), + impl_debug, + impl_partialeq, + with_derive_default => Builder::derive_default, + with_derive_hash => Builder::derive_hash, + with_derive_partialeq => Builder::derive_partialeq, + with_derive_partialord => Builder::derive_partialord, + with_derive_eq => Builder::derive_eq, + with_derive_ord => Builder::derive_ord, + no_derive_default => |b, _| b.derive_default(false), + no_prepend_enum_name => |b, _| b.prepend_enum_name(false), + no_include_path_detection => |b, _| b.detect_include_paths(false), + fit_macro_constant_types => Builder::fit_macro_constants, + time_phases, + use_array_pointers_in_arguments => Builder::array_pointers_in_arguments, + wasm_import_module_name, + extern_fn_block_attrs => Builder::extern_fn_block_attrs, + ctypes_prefix, + anon_fields_prefix, + generate => Builder::with_codegen_config, + emit_clang_ast => |b, _| b.emit_clang_ast(), + emit_ir => |b, _| b.emit_ir(), + emit_ir_graphviz, + enable_cxx_namespaces => |b, _| b.enable_cxx_namespaces(), + enable_function_attribute_detection => |b, _| b.enable_function_attribute_detection(), + disable_name_namespacing => |b, _| b.disable_name_namespacing(), + disable_nested_struct_naming => |b, _| b.disable_nested_struct_naming(), + disable_untagged_union => |b, _| b.disable_untagged_union(), + disable_header_comment => |b, _| b.disable_header_comment(), + ignore_functions => |b, _| b.ignore_functions(), + ignore_methods => |b, _| b.ignore_methods(), + no_convert_floats => |b, _| b.no_convert_floats(), + no_doc_comments => |b, _| b.generate_comments(false), + no_recursive_allowlist => |b, _| b.allowlist_recursively(false), + objc_extern_crate, + nonnull_references => |b, _| b.generate_cxx_nonnull_references(true), + generate_block, + generate_cstr, + block_extern_crate, + opaque_type, + raw_line, + use_core => |b, _| b.use_core(), + distrust_clang_mangling => |b, _| b.trust_clang_mangling(false), + conservative_inline_namespaces => |b, _| b.conservative_inline_namespaces(), + generate_inline_functions, + allowlist_function, + allowlist_type, + allowlist_var, + allowlist_file, + allowlist_item, + clang_args => Builder::clang_arg, + no_record_matches => |b, _| b.record_matches(false), + no_size_t_is_usize => |b, _| b.size_t_is_usize(false), + no_rustfmt_bindings => |b, _| b.formatter(Formatter::None), + formatter, + no_partialeq, + no_copy, + no_debug, + no_default, + no_hash, + must_use_type, + dynamic_loading => Builder::dynamic_library_name, + dynamic_link_require_all, + prefix_link_name => |b, prefix| b.parse_callbacks(Box::new(PrefixLinkNameCallback { prefix })), + respect_cxx_access_specs, + translate_enum_integer_types, + c_naming, + explicit_padding, + use_specific_virtual_function_receiver, + use_distinct_char16_t, + represent_cxx_operators, + vtable_generation, + sort_semantically, + merge_extern_blocks, + override_abi => |b, (abi, regex)| b.override_abi(abi, regex), + wrap_unsafe_ops, + clang_macro_fallback => |b, _| b.clang_macro_fallback(), + clang_macro_fallback_build_dir, + flexarray_dst, + wrap_static_fns, + wrap_static_fns_path, + wrap_static_fns_suffix, + default_visibility, + generate_deleted_functions, + generate_pure_virtual_functions, + generate_private_functions, + } + ); let mut values = module_raw_line.into_iter(); while let Some(module) = values.next() { @@ -931,46 +990,6 @@ where builder = builder.module_raw_line(module, line); } - if use_core { - builder = builder.use_core(); - } - - if distrust_clang_mangling { - builder = builder.trust_clang_mangling(false); - } - - if conservative_inline_namespaces { - builder = builder.conservative_inline_namespaces(); - } - - if generate_inline_functions { - builder = builder.generate_inline_functions(true); - } - - for regex in allowlist_function { - builder = builder.allowlist_function(regex); - } - - for regex in allowlist_type { - builder = builder.allowlist_type(regex); - } - - for regex in allowlist_var { - builder = builder.allowlist_var(regex); - } - - for file in allowlist_file { - builder = builder.allowlist_file(file); - } - - for item in allowlist_item { - builder = builder.allowlist_item(item); - } - - for arg in clang_args { - builder = builder.clang_arg(arg); - } - let output = if let Some(path) = &output { let file = File::create(path)?; if let Some(depfile) = depfile { @@ -988,172 +1007,11 @@ where builder.dump_preprocessed_input()?; } - if no_record_matches { - builder = builder.record_matches(false); - } - - if no_size_t_is_usize { - builder = builder.size_t_is_usize(false); - } - - if no_rustfmt_bindings { - builder = builder.formatter(Formatter::None); - } - - if let Some(formatter) = formatter { - builder = builder.formatter(formatter); - } - if let Some(path) = rustfmt_configuration_file { builder = builder.rustfmt_configuration_file(Some(path)); } - for regex in no_partialeq { - builder = builder.no_partialeq(regex); - } - - for regex in no_copy { - builder = builder.no_copy(regex); - } - - for regex in no_debug { - builder = builder.no_debug(regex); - } - - for regex in no_default { - builder = builder.no_default(regex); - } - - for regex in no_hash { - builder = builder.no_hash(regex); - } - - for regex in must_use_type { - builder = builder.must_use_type(regex); - } - - if let Some(dynamic_library_name) = dynamic_loading { - builder = builder.dynamic_library_name(dynamic_library_name); - } - - if dynamic_link_require_all { - builder = builder.dynamic_link_require_all(true); - } - - if let Some(prefix_link_name) = prefix_link_name { - #[derive(Debug)] - struct PrefixLinkNameCallback { - prefix: String, - } - - impl bindgen::callbacks::ParseCallbacks for PrefixLinkNameCallback { - fn generated_link_name_override( - &self, - item_info: bindgen::callbacks::ItemInfo<'_>, - ) -> Option { - let mut prefix = self.prefix.clone(); - prefix.push_str(item_info.name); - Some(prefix) - } - } - - builder = builder.parse_callbacks(Box::new(PrefixLinkNameCallback { - prefix: prefix_link_name, - })) - } - - if respect_cxx_access_specs { - builder = builder.respect_cxx_access_specs(true); - } - - if translate_enum_integer_types { - builder = builder.translate_enum_integer_types(true); - } - - if c_naming { - builder = builder.c_naming(true); - } - - if explicit_padding { - builder = builder.explicit_padding(true); - } - - if vtable_generation { - builder = builder.vtable_generation(true); - } - - if sort_semantically { - builder = builder.sort_semantically(true); - } - - if merge_extern_blocks { - builder = builder.merge_extern_blocks(true); - } - - for (abi, regex) in override_abi { - builder = builder.override_abi(abi, regex); - } - - if wrap_unsafe_ops { - builder = builder.wrap_unsafe_ops(true); - } - - if clang_macro_fallback { - builder = builder.clang_macro_fallback(); - } - - if let Some(path) = clang_macro_fallback_build_dir { - builder = builder.clang_macro_fallback_build_dir(path); - } - - if flexarray_dst { - builder = builder.flexarray_dst(true); - } - - #[derive(Debug)] - struct CustomDeriveCallback { - derives: Vec, - kind: Option, - regex_set: bindgen::RegexSet, - } - - impl bindgen::callbacks::ParseCallbacks for CustomDeriveCallback { - fn cli_args(&self) -> Vec { - let mut args = vec![]; - - let flag = match &self.kind { - None => "--with-derive-custom", - Some(TypeKind::Struct) => "--with-derive-custom-struct", - Some(TypeKind::Enum) => "--with-derive-custom-enum", - Some(TypeKind::Union) => "--with-derive-custom-union", - }; - - let derives = self.derives.join(","); - - for item in self.regex_set.get_items() { - args.extend_from_slice(&[ - flag.to_owned(), - format!("{}={}", item, derives), - ]); - } - - args - } - - fn add_derives( - &self, - info: &bindgen::callbacks::DeriveInfo<'_>, - ) -> Vec { - if self.kind.map(|kind| kind == info.kind).unwrap_or(true) && - self.regex_set.matches(info.name) - { - return self.derives.clone(); - } - vec![] - } - } - - for (custom_derives, kind, name) in [ + for (custom_derives, kind, _name) in [ (with_derive_custom, None, "--with-derive-custom"), ( with_derive_custom_struct, @@ -1171,11 +1029,17 @@ where "--with-derive-custom-union", ), ] { - let name = emit_diagnostics.then_some(name); + #[cfg(feature = "experimental")] + let name = emit_diagnostics.then_some(_name); + for (derives, regex) in custom_derives { - let mut regex_set = RegexSet::new(); + let mut regex_set = RegexSet::default(); regex_set.insert(regex); + + #[cfg(feature = "experimental")] regex_set.build_with_diagnostics(false, name); + #[cfg(not(feature = "experimental"))] + regex_set.build(false); builder = builder.parse_callbacks(Box::new(CustomDeriveCallback { derives, @@ -1185,50 +1049,7 @@ where } } - #[derive(Debug)] - struct CustomAttributeCallback { - attributes: Vec, - kind: Option, - regex_set: bindgen::RegexSet, - } - - impl bindgen::callbacks::ParseCallbacks for CustomAttributeCallback { - fn cli_args(&self) -> Vec { - let mut args = vec![]; - - let flag = match &self.kind { - None => "--with-attribute-custom", - Some(TypeKind::Struct) => "--with-attribute-custom-struct", - Some(TypeKind::Enum) => "--with-attribute-custom-enum", - Some(TypeKind::Union) => "--with-attribute-custom-union", - }; - - let attributes = self.attributes.join(","); - - for item in self.regex_set.get_items() { - args.extend_from_slice(&[ - flag.to_owned(), - format!("{}={}", item, attributes), - ]); - } - - args - } - - fn add_attributes( - &self, - info: &bindgen::callbacks::AttributeInfo<'_>, - ) -> Vec { - if self.kind.map(|kind| kind == info.kind).unwrap_or(true) && - self.regex_set.matches(info.name) - { - return self.attributes.clone(); - } - vec![] - } - } - - for (custom_attributes, kind, name) in [ + for (custom_attributes, kind, _name) in [ (with_attribute_custom, None, "--with-attribute-custom"), ( with_attribute_custom_struct, @@ -1246,11 +1067,17 @@ where "--with-attribute-custom-union", ), ] { - let name = emit_diagnostics.then_some(name); + #[cfg(feature = "experimental")] + let name = emit_diagnostics.then_some(_name); + for (attributes, regex) in custom_attributes { - let mut regex_set = RegexSet::new(); + let mut regex_set = RegexSet::default(); regex_set.insert(regex); + + #[cfg(feature = "experimental")] regex_set.build_with_diagnostics(false, name); + #[cfg(not(feature = "experimental"))] + regex_set.build(false); builder = builder.parse_callbacks(Box::new(CustomAttributeCallback { @@ -1261,25 +1088,74 @@ where } } - if wrap_static_fns { - builder = builder.wrap_static_fns(true); + #[cfg(feature = "experimental")] + if emit_diagnostics { + builder = builder.emit_diagnostics(); } - if let Some(path) = wrap_static_fns_path { - builder = builder.wrap_static_fns_path(path); - } + Ok((builder, output, verbose)) +} - if let Some(suffix) = wrap_static_fns_suffix { - builder = builder.wrap_static_fns_suffix(suffix); - } +/// Trait for CLI arguments that can be applied to a [`Builder`]. +trait CliArg { + /// The value of this argument. + type Value; + + /// Apply the current argument to the passed [`Builder`]. + fn apply( + self, + builder: Builder, + f: impl Fn(Builder, Self::Value) -> Builder, + ) -> Builder; +} + +/// Boolean arguments are applied when they evaluate to `true`. +impl CliArg for bool { + type Value = bool; + + fn apply( + self, + mut builder: Builder, + f: impl Fn(Builder, Self::Value) -> Builder, + ) -> Builder { + if self { + builder = f(builder, self); + } - if let Some(visibility) = default_visibility { - builder = builder.default_visibility(visibility); + builder } +} - if emit_diagnostics { - builder = builder.emit_diagnostics(); +/// Optional arguments are applied when they are `Some`. +impl CliArg for Option { + type Value = T; + + fn apply( + self, + mut builder: Builder, + f: impl Fn(Builder, Self::Value) -> Builder, + ) -> Builder { + if let Some(value) = self { + builder = f(builder, value); + } + + builder } +} - Ok((builder, output, verbose)) +/// Multiple valued arguments are applied once for each value. +impl CliArg for Vec { + type Value = T; + + fn apply( + self, + mut builder: Builder, + f: impl Fn(Builder, Self::Value) -> Builder, + ) -> Builder { + for value in self { + builder = f(builder, value); + } + + builder + } } diff --git a/bindgen/options/mod.rs b/bindgen/options/mod.rs index e4c03ecd4d..b9b33a850b 100644 --- a/bindgen/options/mod.rs +++ b/bindgen/options/mod.rs @@ -4,13 +4,15 @@ #[macro_use] mod helpers; mod as_args; +#[cfg(feature = "__cli")] +pub(crate) mod cli; use crate::callbacks::ParseCallbacks; use crate::codegen::{ AliasVariation, EnumVariation, MacroTypeVariation, NonCopyUnionStyle, }; use crate::deps::DepfileSpec; -use crate::features::{RustFeatures, RustTarget}; +use crate::features::{RustEdition, RustFeatures, RustTarget}; use crate::regex_set::RegexSet; use crate::Abi; use crate::Builder; @@ -151,6 +153,64 @@ macro_rules! options { } options! { + /// Whether to specify the type of a virtual function receiver + use_specific_virtual_function_receiver: bool { + methods: { + /// Normally, virtual functions have void* as their 'this' type. + /// If this flag is enabled, override that behavior to indicate a + /// pointer of the specific type. + /// Disabled by default. + pub fn use_specific_virtual_function_receiver(mut self, doit: bool) -> Builder { + self.options.use_specific_virtual_function_receiver = doit; + self + } + }, + as_args: "--use-specific-virtual-function-receiver", + }, + + /// Whether we should distinguish between C++'s `char16_t` and `u16`. + /// The C++ type `char16_t` is its own special type; it's not a typedef + /// of some other integer (this differs from C). + /// As standard, bindgen represents C++ `char16_t` as `u16`. + /// Rust does not have a `std::os::raw::c_char16_t` type, and thus + /// we can't use a built-in Rust type in the generated bindings (and + /// nor would it be appropriate as it's a C++-specific type.) + /// But for some uses of bindgen, especially when downstream + /// post-processing occurs, it's important to distinguish `char16_t` + /// from normal `uint16_t`. When this option is enabled, bindgen + /// generates a fake type called `bindgen_cchar16_t`. Downstream + /// code post-processors should arrange to replace this with a + /// real type. + use_distinct_char16_t: bool { + methods: { + /// If this is true, denote `char16_t` as a separate type from `u16`. + /// Disabled by default. + pub fn use_distinct_char16_t(mut self, doit: bool) -> Builder { + self.options.use_distinct_char16_t = doit; + self + } + }, + as_args: "--use-distinct-char16-t", + }, + /// Whether we should output C++ overloaded operators. By itself, + /// this option is not sufficient to produce valid output, because + /// such operators will have names that are not acceptable Rust + /// names (for example `operator=`). If you use this option, you'll also + /// have to rename the resulting functions - for example by using + /// [`ParseCallbacks::generated_name_override`]. + represent_cxx_operators: bool { + methods: { + /// If this is true, output existence of C++ overloaded operators. + /// At present, only operator= is noted. + /// Disabled by default. + pub fn represent_cxx_operators(mut self, doit: bool) -> Builder { + self.options.represent_cxx_operators = doit; + self + } + }, + as_args: "--represent-cxx-operators", + }, + /// Types that have been blocklisted and should not appear anywhere in the generated code. blocklisted_types: RegexSet { methods: { @@ -481,13 +541,18 @@ options! { /// /// This is similar to the [`Builder::rustified_enum`] style, but the `enum` is /// tagged with the `#[non_exhaustive]` attribute. + /// + /// **Use this with caution**, creating an instance of a Rust `enum` with an + /// invalid value will cause undefined behaviour, even if it's tagged with + /// `#[non_exhaustive]`. To avoid this, use the [`Builder::newtype_enum`] style + /// instead. pub fn rustified_non_exhaustive_enum>(mut self, arg: T) -> Builder { self.options.rustified_non_exhaustive_enums.insert(arg); self } } }, - as_args: "--rustified-non-exhaustive-enums", + as_args: "--rustified-non-exhaustive-enum", }, /// `enum`s marked as modules of constants. constified_enum_modules: RegexSet { @@ -1141,7 +1206,7 @@ options! { }, as_args: |module_lines, args| { for (module, lines) in module_lines { - for line in lines.iter() { + for line in lines { args.push("--module-raw-line".to_owned()); args.push(module.clone().into()); args.push(line.clone().into()); @@ -1232,6 +1297,11 @@ options! { // This field is handled specially inside the macro. as_args: ignore, }, + /// The set of arguments to be passed straight through to Clang for the macro fallback code. + fallback_clang_args: Vec> { + methods: {}, + as_args: ignore, + }, /// Tuples of unsaved file contents of the form (name, contents). input_header_contents: Vec<(Box, Box)> { methods: { @@ -1409,6 +1479,26 @@ options! { }, as_args: |value, args| (!value).as_args(args, "--no-doc-comments"), }, + /// Whether to generate [`NonNull`] pointers for C++ references. + /// + /// [`NonNull`]: core::ptr::NonNull + generate_cxx_nonnull_references: bool { + default: false, + methods: { + /// Generate `NonNull` pointers in place of raw pointers for C++ + /// references. + /// + /// This option is disabled by default: + /// + /// Enabling it erases information about constness in generated + /// code, and `NonNull` is more cumbersome to use than raw pointers. + pub fn generate_cxx_nonnull_references(mut self, doit: bool) -> Self { + self.options.generate_cxx_nonnull_references = doit; + self + } + }, + as_args: |value, args| value.as_args(args, "--nonnull-references"), + }, /// Whether to generate inline functions. generate_inline_functions: bool { methods: { @@ -1419,10 +1509,8 @@ options! { /// Note that they will usually not work. However you can use `-fkeep-inline-functions` /// or `-fno-inline-functions` if you are responsible of compiling the library to make /// them callable. - #[cfg_attr( - feature = "experimental", - doc = "\nCheck the [`Builder::wrap_static_fns`] method for an alternative." - )] + /// + /// Check the [`Builder::wrap_static_fns`] method for an alternative. pub fn generate_inline_functions(mut self, doit: bool) -> Self { self.options.generate_inline_functions = doit; self @@ -1609,9 +1697,26 @@ options! { args.push(rust_target.to_string()); }, }, + /// The Rust edition to use for code generation. + rust_edition: Option { + methods: { + /// Specify the Rust target edition. + /// + /// The default edition is the latest edition supported by the chosen Rust target. + pub fn rust_edition(mut self, rust_edition: RustEdition) -> Self { + self.options.rust_edition = Some(rust_edition); + self + } + } + as_args: |edition, args| { + if let Some(edition) = edition { + args.push("--rust-edition".to_owned()); + args.push(edition.to_string()); + } + }, + }, /// Features to be enabled. They are derived from `rust_target`. rust_features: RustFeatures { - default: RustTarget::default().into(), methods: {}, // This field cannot be set from the CLI, as_args: ignore, @@ -1811,6 +1916,25 @@ options! { }, as_args: "--use-array-pointers-in-arguments", }, + /// Attributes to add to all `extern` blocks. + extern_fn_block_attrs: Vec { + methods: { + /// Add an attribute to all the `extern` blocks generated by `bindgen`. + /// + /// This can be used to add attributes such as `#[link(...)]` to all + /// the `extern` blocks. + pub fn extern_fn_block_attrs>(mut self, attr: T) -> Self { + self.options.extern_fn_block_attrs.push(attr.into()); + self + } + }, + as_args: |attrs, args| { + for attr in attrs { + args.push("--extern-fn-block-attrs".to_owned()); + args.push(attr.clone()); + } + }, + }, /// The name of the `wasm_import_module`. wasm_import_module_name: Option { methods: { @@ -1822,7 +1946,9 @@ options! { mut self, import_name: T, ) -> Self { - self.options.wasm_import_module_name = Some(import_name.into()); + self.options.extern_fn_block_attrs.push(format!( + "#[link(wasm_import_module = \"{}\")]", import_name.into() + )); self } }, @@ -2013,7 +2139,7 @@ options! { for (abi, set) in overrides { for item in set.get_items() { args.push("--override-abi".to_owned()); - args.push(format!("{}={}", item, abi)); + args.push(format!("{item}={abi}")); } } }, @@ -2021,8 +2147,7 @@ options! { /// Whether to generate wrappers for `static` functions. wrap_static_fns: bool { methods: { - #[cfg(feature = "experimental")] - /// Set whether to generate wrappers for `static`` functions. + /// Set whether to generate wrappers for `static` functions. /// /// Passing `true` to this method will generate a C source file with non-`static` /// functions that call the `static` functions found in the input headers and can be @@ -2040,7 +2165,6 @@ options! { /// The suffix to be added to the function wrappers for `static` functions. wrap_static_fns_suffix: Option { methods: { - #[cfg(feature = "experimental")] /// Set the suffix added to the wrappers for `static` functions. /// /// This option only comes into effect if `true` is passed to the @@ -2057,7 +2181,6 @@ options! { /// The path of the file where the wrappers for `static` functions will be emitted. wrap_static_fns_path: Option { methods: { - #[cfg(feature = "experimental")] /// Set the path for the source code file that would be created if any wrapper /// functions must be generated due to the presence of `static` functions. /// @@ -2152,4 +2275,58 @@ options! { }, as_args: "--clang-macro-fallback-build-dir", } + /// Whether to always report C++ "deleted" functions. + generate_deleted_functions: bool { + methods: { + /// Set whether to generate C++ functions even marked "=deleted" + /// + /// Although not useful to call these functions, downstream code + /// generators may need to know whether they've been deleted in + /// order to determine the relocatability of a C++ type + /// (specifically by virtue of which constructors exist.) + pub fn generate_deleted_functions(mut self, doit: bool) -> Self { + self.options.generate_deleted_functions = doit; + self + } + + }, + as_args: "--generate-deleted-functions", + }, + /// Whether to always report C++ "pure virtual" functions. + generate_pure_virtual_functions: bool { + methods: { + /// Set whether to generate C++ functions that are pure virtual. + /// + /// These functions can't be called, so the only reason + /// to generate them is if downstream postprocessors + /// need to know of their existence. This is necessary, + /// for instance, to determine whether a type itself is + /// pure virtual and thus can't be allocated. + /// Downstream code generators may choose to make code to + /// allow types to be allocated but need to avoid doing so + /// if the type contains pure virtual functions. + pub fn generate_pure_virtual_functions(mut self, doit: bool) -> Self { + self.options.generate_pure_virtual_functions = doit; + self + } + + }, + as_args: "--generate-pure-virtual-functions", + }, + /// Whether to always report C++ "private" functions. + generate_private_functions: bool { + methods: { + /// Set whether to generate C++ functions that are private. + /// + /// These functions can't be called, so the only reason + /// to generate them is if downstream postprocessors + /// need to know of their existence. + pub fn generate_private_functions(mut self, doit: bool) -> Self { + self.options.generate_private_functions = doit; + self + } + + }, + as_args: "--generate-private-functions", + }, } diff --git a/bindgen/regex_set.rs b/bindgen/regex_set.rs index 7f40af3c79..32279557b5 100644 --- a/bindgen/regex_set.rs +++ b/bindgen/regex_set.rs @@ -6,7 +6,7 @@ use std::cell::Cell; /// A dynamic set of regular expressions. #[derive(Clone, Debug, Default)] -pub struct RegexSet { +pub(crate) struct RegexSet { items: Vec>, /// Whether any of the items in the set was ever matched. The length of this /// vector is exactly the length of `items`. @@ -17,18 +17,13 @@ pub struct RegexSet { } impl RegexSet { - /// Create a new RegexSet - pub fn new() -> RegexSet { - RegexSet::default() - } - /// Is this set empty? - pub fn is_empty(&self) -> bool { + pub(crate) fn is_empty(&self) -> bool { self.items.is_empty() } /// Insert a new regex into this set. - pub fn insert(&mut self, string: S) + pub(crate) fn insert(&mut self, string: S) where S: AsRef, { @@ -38,13 +33,13 @@ impl RegexSet { } /// Returns slice of String from its field 'items' - pub fn get_items(&self) -> &[Box] { + pub(crate) fn get_items(&self) -> &[Box] { &self.items } /// Returns an iterator over regexes in the set which didn't match any /// strings yet. - pub fn unmatched_items(&self) -> impl Iterator { + pub(crate) fn unmatched_items(&self) -> impl Iterator { self.items.iter().enumerate().filter_map(move |(i, item)| { if !self.record_matches || self.matched[i].get() { return None; @@ -54,28 +49,29 @@ impl RegexSet { }) } - /// Construct a RegexSet from the set of entries we've accumulated. + /// Construct a `RegexSet` from the set of entries we've accumulated. /// /// Must be called before calling `matches()`, or it will always return /// false. #[inline] - pub fn build(&mut self, record_matches: bool) { - self.build_inner(record_matches, None) + #[allow(unused)] + pub(crate) fn build(&mut self, record_matches: bool) { + self.build_inner(record_matches, None); } #[cfg(all(feature = "__cli", feature = "experimental"))] - /// Construct a RegexSet from the set of entries we've accumulated and emit diagnostics if the + /// Construct a `RegexSet` from the set of entries we've accumulated and emit diagnostics if the /// name of the regex set is passed to it. /// /// Must be called before calling `matches()`, or it will always return /// false. #[inline] - pub fn build_with_diagnostics( + pub(crate) fn build_with_diagnostics( &mut self, record_matches: bool, name: Option<&'static str>, ) { - self.build_inner(record_matches, name) + self.build_inner(record_matches, name); } #[cfg(all(not(feature = "__cli"), feature = "experimental"))] @@ -90,7 +86,7 @@ impl RegexSet { record_matches: bool, name: Option<&'static str>, ) { - self.build_inner(record_matches, name) + self.build_inner(record_matches, name); } fn build_inner( @@ -98,12 +94,12 @@ impl RegexSet { record_matches: bool, _name: Option<&'static str>, ) { - let items = self.items.iter().map(|item| format!("^({})$", item)); + let items = self.items.iter().map(|item| format!("^({item})$")); self.record_matches = record_matches; self.set = match RxSet::new(items) { Ok(x) => Some(x), Err(e) => { - warn!("Invalid regex in {:?}: {:?}", self.items, e); + warn!("Invalid regex in {:?}: {e:?}", self.items); #[cfg(feature = "experimental")] if let Some(name) = _name { invalid_regex_warning(self, e, name); @@ -114,14 +110,13 @@ impl RegexSet { } /// Does the given `string` match any of the regexes in this set? - pub fn matches(&self, string: S) -> bool + pub(crate) fn matches(&self, string: S) -> bool where S: AsRef, { let s = string.as_ref(); - let set = match self.set { - Some(ref set) => set, - None => return false, + let Some(ref set) = self.set else { + return false; }; if !self.record_matches { @@ -132,7 +127,7 @@ impl RegexSet { if !matches.matched_any() { return false; } - for i in matches.iter() { + for i in &matches { self.matched[i].set(true); } @@ -193,7 +188,7 @@ fn invalid_regex_warning( } diagnostic.add_annotation( - format!("This regular expression was passed via `{}`.", name), + format!("This regular expression was passed via `{name}`."), Level::Note, ); diff --git a/bindgen/time.rs b/bindgen/time.rs index c13a640c46..2952e36f76 100644 --- a/bindgen/time.rs +++ b/bindgen/time.rs @@ -29,23 +29,23 @@ impl<'a> Timer<'a> { /// Returns the time elapsed since the timer's creation pub fn elapsed(&self) -> Duration { - Instant::now() - self.start + self.start.elapsed() } fn print_elapsed(&mut self) { if self.output { let elapsed = self.elapsed(); let time = (elapsed.as_secs() as f64) * 1e3 + - (elapsed.subsec_nanos() as f64) / 1e6; + f64::from(elapsed.subsec_nanos()) / 1e6; let stderr = io::stderr(); // Arbitrary output format, subject to change. - writeln!(stderr.lock(), " time: {:>9.3} ms.\t{}", time, self.name) + writeln!(stderr.lock(), " time: {time:>9.3} ms.\t{}", self.name) .expect("timer write should not fail"); } } } -impl<'a> Drop for Timer<'a> { +impl Drop for Timer<'_> { fn drop(&mut self) { self.print_elapsed(); } diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index daaed04081..ac57aaad64 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -8,9 +8,9 @@ - [Create a `wrapper.h` Header](./tutorial-2.md) - [Create a `build.rs` File](./tutorial-3.md) - [Include the Generated Bindings in `src/lib.rs`](./tutorial-4.md) - - [Write a Sanity Test](./tutorial-5.md) + - [Write a Smoke Test](./tutorial-5.md) - [Publish Your Crate!](./tutorial-6.md) - - [Bindings for non-system libraries](./non-system-libraries.md) + - [Bindings for Non-System Libraries](./non-system-libraries.md) - [Command Line Usage](./command-line-usage.md) - [Customizing the Generated Bindings](./customizing-generated-bindings.md) - [Allowlisting](./allowlisting.md) @@ -20,11 +20,11 @@ - [Preventing the Derivation of `Copy` and `Clone`](./nocopy.md) - [Preventing the Derivation of `Debug`](./nodebug.md) - [Preventing the Derivation of `Default`](./nodefault.md) - - [Annotating types with `#[must-use]`](./must-use-types.md) - - [Field visibility](./visibility.md) - - [Code formatting](./code-formatting.md) + - [Annotating Types with `#[must-use]`](./must-use-types.md) + - [Field Visibility](./visibility.md) + - [Code Formatting](./code-formatting.md) - [Generating Bindings to C++](./cpp.md) -- [Generating Bindings to Objective-c](./objc.md) +- [Generating Bindings to Objective-C](./objc.md) - [Using Unions](./using-unions.md) - [Using Bitfields](./using-bitfields.md) - [Using Flexible Array Members](./using-fam.md) diff --git a/book/src/code-formatting.md b/book/src/code-formatting.md index 9c82e83a32..368535c452 100644 --- a/book/src/code-formatting.md +++ b/book/src/code-formatting.md @@ -47,8 +47,7 @@ fn main() { assert!( output.status.success(), - "Unsuccessful status code when running `rustup`: {:?}", - output + "Unsuccessful status code when running `rustup`: {output:?}", ); let rustfmt_path = diff --git a/book/src/command-line-usage.md b/book/src/command-line-usage.md index b3356d70c7..051a63efad 100644 --- a/book/src/command-line-usage.md +++ b/book/src/command-line-usage.md @@ -13,7 +13,7 @@ directory to your `$PATH` to use `bindgen`. output file path for the generated bindings. If the output file path is not supplied, the bindings are printed to `stdout`. -If we wanted to generated Rust FFI bindings from a C header named `input.h` and +If we wanted to generate Rust FFI bindings from a C header named `input.h` and put them in the `bindings.rs` file, we would invoke `bindgen` like this: ```bash diff --git a/book/src/cpp.md b/book/src/cpp.md index db368f6787..22e9dcf120 100644 --- a/book/src/cpp.md +++ b/book/src/cpp.md @@ -7,7 +7,7 @@ be nowhere near as nice as using them in C++. You will have to manually call constructors, destructors, overloaded operators, etc yourself. When passing in header files, the file will automatically be treated as C++ if -it ends in `.hpp`. If it doesn't, adding `-x c++` clang args can be used to +it ends in `.hpp`. If it doesn't, adding `clang_args(["-x", "c++"])` can be used to force C++ mode. You probably also want to use `-std=c++14` or similar clang args as well. diff --git a/book/src/faq.md b/book/src/faq.md index bbaaab6368..59699ac757 100644 --- a/book/src/faq.md +++ b/book/src/faq.md @@ -47,18 +47,18 @@ creates linking errors. However, if you are compiling the C/C++ yourself (rather than using a system shared library, for example), then you can pass `-fkeep-inline-functions` or `-fno-inline-functions` to `gcc` or `clang`, and invoke `bindgen` with either -the `bindgen::Builder::generate_inline_functions` method or the -`--generate-inline-functions` flag. +the [`bindgen::Builder::generate_inline_functions`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.generate_inline_functions) +method or the `--generate-inline-functions` flag. Note that these functions and methods are usually marked inline for a reason: they tend to be hot. The above workaround makes them an out-of-line call, which might not provide acceptable performance. As an alternative, you can invoke `bindgen` with either the -`bindgen::Builder::wrap_static_fns` method or the `--wrap-static-fns` flag. -Which generates a C source file that can be compiled against the input headers -to produce Rust headers for `static` and `static inline` functions. See [How to -handle `static inline` functions](https://github.com/rust-lang/rust-bindgen/discussions/2405) +[`bindgen::Builder::wrap_static_fns`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.wrap_static_fns) +method or the `--wrap-static-fns` flag. That generates a C source file that can +be compiled against the input headers to produce Rust bindings for `static` and +`static inline` functions. See [How to handle `static inline` functions](https://github.com/rust-lang/rust-bindgen/discussions/2405) for further information. ### Does `bindgen` support the C++ Standard Template Library (STL)? @@ -81,8 +81,8 @@ possible that bindgen will generate padding fields named `__bindgen_padding_N`. As these fields might be present when compiling for one architecture but not for an other, you should not initialize these fields manually when initializing the struct. Instead, use the `Default` trait. You can either enable this when -constructing the `Builder` using the `derive_default` method, or you can -implement this per struct using: +constructing the `Builder` using the [`derive_default`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.derive_default) +method, or you can implement this per struct using: ```rust,ignore impl Default for SRC_DATA { @@ -107,7 +107,7 @@ be automatically initialized by `..Default::default()`. ### How to generate bindings for a custom target? -To generate bindings for a custom target you only need to pass the `--target` +To generate bindings for a custom target you only need to pass the [`--target`](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-target) argument to `libclang`. For example, if you want to generate bindings for the `armv7a-none-eabi` target using the command line, you need to invoke `bindgen` like so: diff --git a/book/src/must-use-types.md b/book/src/must-use-types.md index 490339c9d2..1792e5a485 100644 --- a/book/src/must-use-types.md +++ b/book/src/must-use-types.md @@ -1,11 +1,13 @@ -# Annotating types with `#[must-use]` +# Annotating Types with `#[must-use]` `bindgen` can be instructed to annotate certain types with [`#[must_use]`](https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute). -Some libraries have a common error type, returned by lots of their functions, -which needs to be checked after every call. In these cases it's useful to add `#[must_use]` to this type, so the Rust -compiler emits a warning when the check is missing. +Some libraries have a common error type, returned by many of their functions, +which needs to be checked after every call. In these cases it's useful to add +`#[must_use]` to this type, so the Rust compiler emits a warning when the check +is missing. + ### Library * [`bindgen::Builder::must_use_type`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.must_use_type) diff --git a/book/src/nocopy.md b/book/src/nocopy.md index 8a637a59c3..e0d17ed0cb 100644 --- a/book/src/nocopy.md +++ b/book/src/nocopy.md @@ -4,14 +4,17 @@ basis. Sometimes, it might not understand that although adding `#[derive(Copy, Clone)]` to a translated type definition will compile, it still shouldn't do that for reasons it can't know. In these cases, the `nocopy` annotation can be -used to prevent bindgen to autoderive the `Copy` and `Clone` traits for a type. +used to prevent bindgen from automatically deriving the `Copy` and `Clone` +traits for a type. ### Library +* [`bindgen::Builder::derive_copy`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.derive_copy) * [`bindgen::Builder::no_copy`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.no_copy) ### Command Line +* `--no-derive-copy` * `--no-copy ` ### Annotations diff --git a/book/src/nodebug.md b/book/src/nodebug.md index c412a7dfca..4fa820134b 100644 --- a/book/src/nodebug.md +++ b/book/src/nodebug.md @@ -3,14 +3,16 @@ `bindgen` will attempt to derive the `Debug` traits on a best-effort basis. Sometimes, it might not understand that although adding `#[derive(Debug)]` to a translated type definition will compile, it still shouldn't do that for reasons it can't know. In these cases, the `nodebug` annotation can be -used to prevent bindgen to autoderive the `Debug` traits for a type. +used to prevent bindgen from automatically deriving the `Debug` trait for a type. ### Library +* [`bindgen::Builder::derive_debug`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.derive_debug) * [`bindgen::Builder::no_debug`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.no_debug) ### Command Line +* `--no-derive-debug` * `--no-debug ` ### Annotations diff --git a/book/src/nodefault.md b/book/src/nodefault.md index 37896f6c5c..9561d7c17f 100644 --- a/book/src/nodefault.md +++ b/book/src/nodefault.md @@ -1,16 +1,20 @@ # Preventing the Derivation of `Default` +By default, `Default` is not derived. + `bindgen` will attempt to derive/impl the `Default` traits on a best-effort basis. -Sometimes, we need customize the implement of `Default` for certain types, -In these cases, the `nodefault` annotation can be used to prevent bindgen -to autoderive the `Default` traits for a type. +Sometimes, we need customize the implementation of `Default` for certain types. +In these cases, the `nodefault` annotation can be used to prevent bindgen from +automatically deriving the `Default` trait for a type. ### Library +* [`bindgen::Builder::derive_default`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.derive_default) * [`bindgen::Builder::no_default`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.no_default) ### Command Line +* `--with-derive-default` * `--no-default ` ### Annotations diff --git a/book/src/non-system-libraries.md b/book/src/non-system-libraries.md index b080db80d7..598889d360 100644 --- a/book/src/non-system-libraries.md +++ b/book/src/non-system-libraries.md @@ -20,8 +20,6 @@ library: use std::env; use std::path::PathBuf; -use bindgen::CargoCallbacks; - fn main() { // This is the directory where the `c` library is located. let libdir_path = PathBuf::from("hello") @@ -86,7 +84,7 @@ fn main() { .header(headers_path_str) // Tell cargo to invalidate the built crate whenever any of the // included header files changed. - .parse_callbacks(Box::new(CargoCallbacks::new())) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) // Finish the builder and generate the bindings. .generate() // Unwrap the Result and panic on failure. diff --git a/book/src/objc.md b/book/src/objc.md index ed6f2cb881..3845ed5a2e 100644 --- a/book/src/objc.md +++ b/book/src/objc.md @@ -1,10 +1,10 @@ # Generating Bindings to Objective-C -`bindgen` does not (yet) have full objective-c support but it can generate bindings -for a lot of the apple frameworks without too much blocklisting. +`bindgen` does not (yet) have full Objective-C support, but it can generate +bindings for many of the Apple frameworks without too much blocklisting. -In order to generate bindings, you will need `-x objective-c` as the clang -args. If you'd like to use [block](https://crates.io/crates/block) you will need +In order to generate bindings, you will need `-x objective-c` as a clang arg. If +you'd like to use [block](https://crates.io/crates/block) you will need `-fblocks` as a clang arg as well. Depending on your setup, you may need `--generate-block` to generate the block @@ -12,14 +12,14 @@ function aliases and `--block-extern-crate` to insert a `extern crate block` at the beginning of the generated bindings. The same logic applies to the `--objc-extern-crate` parameter. -The objective-c classes will be represented as a `struct Foo(id)` and a trait -`IFoo` where `Foo` is the objective-c class and `id` is an alias for `*mut -objc::runtime::Object` (the pointer to the objective-c instance). The trait +The Objective-C classes will be represented as a `struct Foo(id)` and a trait +`IFoo` where `Foo` is the Objective-C class and `id` is an alias for `*mut +objc::runtime::Object` (the pointer to the Objective-C instance). The trait `IFoo` is needed to allow for the generated inheritance. -Functions that use or return objective-c pointers of instance `Foo` will return +Functions that use or return Objective-C pointers of instance `Foo` will return `Foo`. The reason this works is because `Foo` represented as `transparent`. -This will be helpful for a lot of objective-c frameworks however there are some +This will be helpful for many Objective-C frameworks. However, there are some cases where functions return `instancetype` which is a type alias for `id` so an occasional `foo.0` may be required. An example of this would in the UIKit framework should you want to add a `UILabel` to a @@ -42,7 +42,7 @@ stands for interface. * Protocols which match to rust traits with prefixes of `P` which stands for Protocol. * Classes will generate `struct Foo(id)` where `Foo` is the class -name and `id` is a pointer to the objective-c Object. +name and `id` is a pointer to the Objective-C Object. * Blocks ## Useful Notes @@ -52,16 +52,16 @@ name and `id` is a pointer to the objective-c Object. [here](https://github.com/rust-lang/rust-bindgen/issues/1211#issuecomment-569804287). * The generated bindings will almost certainly have some conflicts so you will have to blocklist a few things. There are a few cases of the parameters being -poorly named in the objective-c headers. But if you're using anything with +poorly named in the Objective-C headers. But if you're using anything with Core Foundation, you'll find that `time.h` as has a variable called timezone that conflicts with some of the things in `NSCalendar.h`. -* Some small subset of the function headers in the apple frameworks go against -apple's guidelines for parameter names and duplicate the names in the header +* Some small subset of the function headers in the Apple frameworks go against +Apple's guidelines for parameter names and duplicate the names in the header which won't compile as mentioned [here](https://github.com/rust-lang/rust-bindgen/issues/1705). * instancetype return methods does not return `Self` for you given class, it returns a `mut * objc::runtime::Objc` which is aliased as `id`. This is because -objective-c's inheritance doesn't perfectly match that of rusts. +Objective-C's inheritance doesn't perfectly match that of Rust's. * Depending on what you're trying `bindgen` against, you may end up including all of Core Foundation and any other frameworks. This will result in a very long compile time. diff --git a/book/src/requirements.md b/book/src/requirements.md index b701234fad..cf719a0d61 100644 --- a/book/src/requirements.md +++ b/book/src/requirements.md @@ -7,7 +7,7 @@ This page lists the requirements for running `bindgen` and how to get them. `bindgen` leverages `libclang` to preprocess, parse, and type check C and C++ header files. -It is required to use Clang 5.0 or greater. +It is required to use Clang 9.0 or greater. ### Installing Clang @@ -48,10 +48,10 @@ $ port install clang #### Debian-based Linuxes ```bash -# apt install llvm-dev libclang-dev clang +# apt install libclang-dev ``` -Ubuntu 18.04 provides the necessary packages directly. +If you want to use the function `bindgen::Builder::dump_preprocessed_input`, then you also need the package `clang`. #### Arch @@ -75,13 +75,13 @@ Add `export LIBCLANG_PATH=/usr/local/lib` to your profile. #### From source -If your package manager doesn't yet offer Clang 5.0, you'll need to build from +If your package manager doesn't yet offer Clang 9.0, you'll need to build from source. For that, follow the instructions [here](http://clang.llvm.org/get_started.html). Those instructions list optional steps. For `bindgen`: * Checkout and build clang -* Checkout and build the extra-clang-tools +* Checkout and build `clang-tools-extra` * You do not need to checkout or build compiler-rt * You do not need to checkout or build libcxx diff --git a/book/src/tutorial-1.md b/book/src/tutorial-1.md index 464b6b9d71..a26c393b3b 100644 --- a/book/src/tutorial-1.md +++ b/book/src/tutorial-1.md @@ -10,7 +10,7 @@ You can always check the latest version at ```toml [build-dependencies] -bindgen = "0.65.1" +bindgen = "0.71.0" ``` > ⚠️ **Warning** diff --git a/book/src/tutorial-5.md b/book/src/tutorial-5.md index de91d092a1..8e308f82d6 100644 --- a/book/src/tutorial-5.md +++ b/book/src/tutorial-5.md @@ -1,11 +1,11 @@ -# Write a Sanity Test +# Write a Smoke Test -Finally, to tie everything together, let's write a sanity test that round trips +Finally, to tie everything together, let's write a smoke test that round trips some text through compression and decompression, and then asserts that it came back out the same as it went in. This is a little wordy using the raw FFI bindings, but hopefully we wouldn't usually ask people to do this, we'd provide a nice Rust-y API on top of the raw FFI bindings for them. However, since this -is for testing the bindings directly, our sanity test will use the bindings +is for testing the bindings directly, our smoke test will use the bindings directly. The test data I'm round tripping are some Futurama quotes I got off the internet @@ -40,7 +40,7 @@ mod tests { r if r == (BZ_PARAM_ERROR as _) => panic!("BZ_PARAM_ERROR"), r if r == (BZ_MEM_ERROR as _) => panic!("BZ_MEM_ERROR"), r if r == (BZ_OK as _) => {}, - r => panic!("Unknown return value = {}", r), + r => panic!("Unknown return value = {r}"), } // Compress `input` into `compressed_output`. @@ -55,7 +55,7 @@ mod tests { r if r == (BZ_FINISH_OK as _) => panic!("BZ_FINISH_OK"), r if r == (BZ_SEQUENCE_ERROR as _) => panic!("BZ_SEQUENCE_ERROR"), r if r == (BZ_STREAM_END as _) => {}, - r => panic!("Unknown return value = {}", r), + r => panic!("Unknown return value = {r}"), } // Finish the compression stream. @@ -63,7 +63,7 @@ mod tests { match result { r if r == (BZ_PARAM_ERROR as _) => panic!("BZ_PARAM_ERROR"), r if r == (BZ_OK as _) => {}, - r => panic!("Unknown return value = {}", r), + r => panic!("Unknown return value = {r}"), } // Construct a decompression stream. @@ -76,7 +76,7 @@ mod tests { r if r == (BZ_PARAM_ERROR as _) => panic!("BZ_PARAM_ERROR"), r if r == (BZ_MEM_ERROR as _) => panic!("BZ_MEM_ERROR"), r if r == (BZ_OK as _) => {}, - r => panic!("Unknown return value = {}", r), + r => panic!("Unknown return value = {r}"), } // Decompress `compressed_output` into `decompressed_output`. @@ -92,7 +92,7 @@ mod tests { r if r == (BZ_MEM_ERROR as _) => panic!("BZ_MEM_ERROR"), r if r == (BZ_OK as _) => panic!("BZ_OK"), r if r == (BZ_STREAM_END as _) => {}, - r => panic!("Unknown return value = {}", r), + r => panic!("Unknown return value = {r}"), } // Close the decompression stream. @@ -100,7 +100,7 @@ mod tests { match result { r if r == (BZ_PARAM_ERROR as _) => panic!("BZ_PARAM_ERROR"), r if r == (BZ_OK as _) => {}, - r => panic!("Unknown return value = {}", r), + r => panic!("Unknown return value = {r}"), } assert_eq!(input, &decompressed_output[..]); diff --git a/book/src/using-bitfields.md b/book/src/using-bitfields.md index 8929f73705..6aaab2203d 100644 --- a/book/src/using-bitfields.md +++ b/book/src/using-bitfields.md @@ -15,7 +15,7 @@ pre-existing definition for the bitfield unit type. ## Bitfield examples -For this discussion, we will use the following C type definitions and functions. +For this discussion, we will use the following C type definitions and functions: ```c typedef struct { unsigned int a: 1; @@ -76,7 +76,9 @@ StructWithBitfields: a:1, b:1, c:0 To create a new bitfield in Rust, use the bitfield allocation unit constructor. -Note: This requires the Builder's derive_default to be set to true, otherwise the necessary Default functions won't be generated. +Note: This requires the `Builder`'s [`derive_default`](https://docs.rs/bindgen/latest/bindgen/struct.Builder.html#method.derive_default) +to be set to `true`. Otherwise the necessary `Default` functions won't be +generated. ```rust,ignore let bfield = StructWithBitfields{ diff --git a/ci/test.sh b/ci/test.sh index 11e091f49f..587263804b 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -8,64 +8,15 @@ set -x # Give a pipeline a non-zero exit code if one of its constituents fails set -o pipefail -function llvm_linux_target_triple() { - case "$1" in - 9.0.1) echo "x86_64-linux-gnu-ubuntu-16.04" ;; - *) echo "x86_64-linux-gnu-ubuntu-18.04" ;; - esac -} - -function llvm_macos_target_triple() { - case "$1" in - 9.0.1) echo "x86_64-apple-darwin" ;; - *) echo "arm64-apple-darwin22.0" ;; - esac -} - -function llvm_version_triple() { - case "$1" in - 9.0) echo "9.0.1" ;; - # By default, take the .0 patch release - *) echo "$1.0" ;; - esac -} - -function llvm_base_url() { - local llvm_version_triple=$1 - echo "https://github.com/llvm/llvm-project/releases/download/llvmorg-$llvm_version_triple" -} - -function llvm_download() { - local base_url=$1 - local arch=$2 - - export LLVM=clang+llvm-${LLVM_VERSION_TRIPLE}-$arch - export LLVM_DIRECTORY="$HOME/.llvm/${LLVM}" - - if [ -d "${LLVM_DIRECTORY}" ]; then - echo "Using cached LLVM download for ${LLVM}..." - else - wget --no-verbose $base_url/${LLVM}.tar.xz - mkdir -p "${LLVM_DIRECTORY}" - tar xf ${LLVM}.tar.xz -C "${LLVM_DIRECTORY}" --strip-components=1 - fi - - export LIBCLANG_PATH="${LLVM_DIRECTORY}/lib" - export LLVM_CONFIG_PATH="${LLVM_DIRECTORY}/bin/llvm-config" -} - -# Download and set up a sane LLVM version set_llvm_env() { - export LLVM_VERSION_TRIPLE=`llvm_version_triple ${LLVM_VERSION}` - local base_url=`llvm_base_url ${LLVM_VERSION_TRIPLE}` - - if [ "$GITHUB_ACTIONS_OS" == "ubuntu-latest" ]; then - llvm_download $base_url `llvm_linux_target_triple ${LLVM_VERSION_TRIPLE}` - export LD_LIBRARY_PATH="${LLVM_DIRECTORY}/lib":${LD_LIBRARY_PATH:-} - else - llvm_download $base_url `llvm_macos_target_triple ${LLVM_VERSION_TRIPLE}` - export DYLD_LIBRARY_PATH="${LLVM_DIRECTORY}/lib":${DYLD_LIBRARY_PATH:-} - fi + export LLVM_CONFIG_PATH=${LLVM_PATH}/bin/llvm-config + echo "LLVM_CONFIG_PATH=$LLVM_CONFIG_PATH" + + export LIBCLANG_PATH=${LLVM_PATH}/lib/ + echo "LIBCLANG_PATH=$LIBCLANG_PATH" + + export CLANG_PATH=${LLVM_PATH}/bin/clang + echo "CLANG_PATH=$CLANG_PATH" } assert_no_diff() { @@ -74,13 +25,8 @@ assert_no_diff() { git diff-index --quiet HEAD } -set_llvm_env - get_cargo_args() { local args="" - if [ ! -z "$RUST_TARGET" ]; then - args+=" --target $RUST_TARGET" - fi if [ "$BINDGEN_RELEASE_BUILD" == "1" ]; then args+=" --release" fi @@ -100,21 +46,93 @@ get_cargo_args() { echo $args } -if [ ! -z "$RUST_CROSS_COMPILER" ]; then - export RUSTFLAGS="-C linker=${RUST_CROSS_COMPILER}-gcc" -fi +set_llvm_env CARGO_ARGS=`get_cargo_args` # Ensure we build without warnings RUSTFLAGS="-Dwarnings" cargo check $CARGO_ARGS -if [ "$BINDGEN_MAIN_TESTS" == "1" ]; then - # Run the tests - (cd bindgen-tests && cargo test $CARGO_ARGS) -fi +# Run the tests +(cd bindgen-tests && cargo test $CARGO_ARGS) assert_no_diff # Run the integration tests (cd bindgen-integration && cargo test $CARGO_ARGS) + +if [ "$BINDGEN_RUST_FOR_LINUX_TEST" == "1" ]; then + # Run the Rust for Linux test + # + # This is intended to be an end-to-end test that runs what Linux kernel + # developers/users would do. It is a quick, build-only test of the Rust code + # in the Linux kernel. + + # Put LLVM binaries in the path for `LLVM=1`. The LLVM `bin` directory should + # go first since there are others in the Ubuntu image. + export PATH="${LLVM_PATH}/bin:${PATH}" + + # Kernel build dependency: `bindgen-cli`, which is under test. + # + # Using `cargo build` (and adding the two common profiles to the `$PATH`) so + # that we can use `$CARGO_ARGS` as is, since `cargo install` does not support + # `--release`. `--target-dir` is used to isolate from other possible tests. + # A cleaner alternative is using `--out-dir`, but it is unstable. + (cd bindgen-cli && cargo build --target-dir ${HOME}/.bindgen $CARGO_ARGS) + export PATH="${HOME}/.bindgen/release:${HOME}/.bindgen/debug:${PATH}" + + # Kernel build dependency: `libelf-dev`. + sudo apt-get update + sudo apt-get install libelf-dev + + # Kernel build dependency: the Rust standard library sources. + # + # `rustup` is used here to install the `rust-src` component (instead of using + # `actions-rs/toolchain`'s `components` option in the workflow step) since we + # only need it for this test, and anyway the action installs `rustup`. + rustup component add rust-src + + # Ideally this should be updated from time to time (e.g. every kernel `-rc1`), + # and each update should only contain this change. + # + # Both commit hashes and tags are supported. + LINUX_VERSION=v6.17-rc2 + + # Download Linux at a specific commit + mkdir -p linux + git -C linux init + git -C linux remote add origin https://github.com/torvalds/linux.git + git -C linux fetch --depth 1 origin ${LINUX_VERSION} + git -C linux checkout FETCH_HEAD + + # Configure Rust for Linux + cat < linux/kernel/configs/rfl-for-bindgen-ci.config +# CONFIG_WERROR is not set + +CONFIG_RUST=y + +CONFIG_SAMPLES=y +CONFIG_SAMPLES_RUST=y + +CONFIG_SAMPLE_RUST_MINIMAL=m +CONFIG_SAMPLE_RUST_PRINT=y + +CONFIG_RUST_PHYLIB_ABSTRACTIONS=y +CONFIG_AX88796B_PHY=y +CONFIG_AX88796B_RUST_PHY=y + +CONFIG_KUNIT=y +CONFIG_RUST_KERNEL_DOCTESTS=y +EOF + + make -C linux LLVM=1 -j$(($(nproc) + 1)) \ + rustavailable \ + defconfig \ + rfl-for-bindgen-ci.config + + # Build Rust for Linux + make -C linux LLVM=1 -j$(($(nproc) + 1)) \ + samples/rust/rust_minimal.o \ + samples/rust/rust_print_main.o \ + drivers/net/phy/ax88796b_rust.o +fi diff --git a/clippy.toml b/clippy.toml index 26a0605343..ec210a9878 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1,5 +1 @@ -disallowed-methods = [ - { path = "clang_sys::CXCursor_TranslationUnit", reason = "This value was changed in clang 15"}, - { path = "clang_sys::CXCursor_LastStmt", reason = "This value was changed in clang 15"} -] missing-docs-in-crate-items = true diff --git a/dist-workspace.toml b/dist-workspace.toml new file mode 100644 index 0000000000..9da713f523 --- /dev/null +++ b/dist-workspace.toml @@ -0,0 +1,28 @@ +[workspace] +members = ["cargo:."] + +# Config for 'dist' +[dist] +# The preferred dist version to use in CI (Cargo.toml SemVer syntax) +cargo-dist-version = "0.28.0" +# CI backends to support +ci = "github" +# The installers to generate for each app +installers = ["shell"] +# Target platforms to build apps for (Rust target-triple syntax) +targets = ["aarch64-apple-darwin", "aarch64-unknown-linux-gnu", "aarch64-pc-windows-msvc", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"] +# Whether to consider the binaries in a package for distribution (defaults true) +dist = false +# Which actions to run on pull requests +pr-run-mode = "plan" +# Whether to install an updater program +install-updater = false +# Path that installers should place binaries in +install-path = "CARGO_HOME" + +[dist.github-custom-runners] +global = "ubuntu-22.04" +aarch64-apple-darwin = "macos-14" +x86_64-apple-darwin = "macos-13" +x86_64-unknown-linux-gnu = "ubuntu-22.04" +aarch64-unknown-linux-gnu = "ubuntu-24.04-arm" diff --git a/triagebot.toml b/triagebot.toml index c196fb3d4d..77eb2925a3 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -25,4 +25,6 @@ trigger_files = [ "**/*.cpp", "**/*.cc", "**/*.hpp", -] \ No newline at end of file +] + +[assign] \ No newline at end of file

(path: P) -> Result where P: AsRef<::std::ffi::OsStr>, { - let library = ::libloading::Library::new(path)?; + let library = unsafe { ::libloading::Library::new(path) }?; unsafe { Self::from_library(library) } } pub unsafe fn from_library(library: L) -> Result @@ -33,11 +34,14 @@ impl TestLib { let foo = unsafe { __library.get(b"foo\0") }.map(|sym| *sym); let bar = unsafe { __library.get(b"bar\0") }.map(|sym| *sym); let baz = unsafe { __library.get(b"baz\0") }.map(|sym| *sym); + let FLUX = unsafe { __library.get::<*mut ::std::os::raw::c_int>(b"FLUX\0") } + .map(|sym| *sym); Ok(TestLib { __library, foo, bar, baz, + FLUX, }) } pub unsafe fn foo( @@ -53,4 +57,7 @@ impl TestLib { pub unsafe fn baz(&self) -> ::std::os::raw::c_int { unsafe { (self.baz.as_ref().expect("Expected function, got error."))() } } + pub unsafe fn FLUX(&self) -> *mut ::std::os::raw::c_int { + *self.FLUX.as_ref().expect("Expected variable, got error.") + } } diff --git a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_objc_class.rs b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_objc_class.rs index c8f7241fcf..34252b10d3 100644 --- a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_objc_class.rs +++ b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_objc_class.rs @@ -3,7 +3,7 @@ use objc::{self, msg_send, sel, sel_impl, class}; #[allow(non_camel_case_types)] pub type id = *mut objc::runtime::Object; -extern "C" { +unsafe extern "C" { pub static mut fooVar: Foo; } #[repr(transparent)] diff --git a/bindgen-tests/tests/headers/16-byte-alignment_1_0.h b/bindgen-tests/tests/headers/16-byte-alignment_1_0.h deleted file mode 100644 index 8a9fd4910e..0000000000 --- a/bindgen-tests/tests/headers/16-byte-alignment_1_0.h +++ /dev/null @@ -1,34 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; - -struct rte_ipv4_tuple { - uint32_t src_addr; - uint32_t dst_addr; - union { - struct { - uint16_t dport; - uint16_t sport; - }; - uint32_t sctp_tag; - }; -}; - -struct rte_ipv6_tuple { - uint8_t src_addr[16]; - uint8_t dst_addr[16]; - union { - struct { - uint16_t dport; - uint16_t sport; - }; - uint32_t sctp_tag; - }; -}; - -union rte_thash_tuple { - struct rte_ipv4_tuple v4; - struct rte_ipv6_tuple v6; -} __attribute__((aligned(16))); diff --git a/bindgen-tests/tests/headers/abi-override.h b/bindgen-tests/tests/headers/abi-override.h index 578659733e..0b0fdcf245 100644 --- a/bindgen-tests/tests/headers/abi-override.h +++ b/bindgen-tests/tests/headers/abi-override.h @@ -1,4 +1,4 @@ -// bindgen-flags: --override-abi=foo=fastcall --override-abi=bar=stdcall --override-abi=boo=efiapi --override-abi=foobar=efiapi --override-abi qux=system +// bindgen-flags: --override-abi=foo=fastcall --override-abi=bar=stdcall --override-abi=boo=efiapi --override-abi=foobar=efiapi --override-abi qux=system --raw-line '#![cfg(target = "i686-pc-windows-msvc")]' void foo(); void bar(); diff --git a/bindgen-tests/tests/headers/anon_struct_in_union_1_0.h b/bindgen-tests/tests/headers/anon_struct_in_union_1_0.h deleted file mode 100644 index 6b59723a3c..0000000000 --- a/bindgen-tests/tests/headers/anon_struct_in_union_1_0.h +++ /dev/null @@ -1,9 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -struct s { - union { - struct inner { - int b; - } field; - } u; -}; diff --git a/bindgen-tests/tests/headers/anon_union_1_0.hpp b/bindgen-tests/tests/headers/anon_union_1_0.hpp deleted file mode 100644 index 3d9ae3dde9..0000000000 --- a/bindgen-tests/tests/headers/anon_union_1_0.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq --rustified-enum ".*" - -template -struct TErrorResult { - enum UnionState { - HasMessage, - HasException, - }; - int mResult; - struct Message; - struct DOMExceptionInfo; - union { - Message* mMessage; - DOMExceptionInfo* mDOMExceptionInfo; - }; - - bool mMightHaveUnreported; - UnionState mUnionState; -}; - -struct ErrorResult : public TErrorResult { -}; diff --git a/bindgen-tests/tests/headers/attribute_warn_unused_result.hpp b/bindgen-tests/tests/headers/attribute_warn_unused_result.hpp index 26fda0910c..bb9c3687e9 100644 --- a/bindgen-tests/tests/headers/attribute_warn_unused_result.hpp +++ b/bindgen-tests/tests/headers/attribute_warn_unused_result.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --rust-target 1.27 --enable-function-attribute-detection +// bindgen-flags: --enable-function-attribute-detection class Foo { public: diff --git a/bindgen-tests/tests/headers/attribute_warn_unused_result_no_attribute_detection.hpp b/bindgen-tests/tests/headers/attribute_warn_unused_result_no_attribute_detection.hpp index 2155030711..25127d9cd0 100644 --- a/bindgen-tests/tests/headers/attribute_warn_unused_result_no_attribute_detection.hpp +++ b/bindgen-tests/tests/headers/attribute_warn_unused_result_no_attribute_detection.hpp @@ -1,5 +1,3 @@ -// bindgen-flags: --rust-target 1.27 - class Foo { public: __attribute__((warn_unused_result)) diff --git a/bindgen-tests/tests/headers/attribute_warn_unused_result_pre_1_27.hpp b/bindgen-tests/tests/headers/attribute_warn_unused_result_pre_1_27.hpp deleted file mode 100644 index 25127d9cd0..0000000000 --- a/bindgen-tests/tests/headers/attribute_warn_unused_result_pre_1_27.hpp +++ /dev/null @@ -1,8 +0,0 @@ -class Foo { -public: - __attribute__((warn_unused_result)) - int foo(int); -}; - -__attribute__((warn_unused_result)) -int foo(int); diff --git a/bindgen-tests/tests/headers/bindgen-union-inside-namespace.hpp b/bindgen-tests/tests/headers/bindgen-union-inside-namespace.hpp index 6a7d3a300c..4007e02566 100644 --- a/bindgen-tests/tests/headers/bindgen-union-inside-namespace.hpp +++ b/bindgen-tests/tests/headers/bindgen-union-inside-namespace.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --rust-target 1.0 --enable-cxx-namespaces +// bindgen-flags: --enable-cxx-namespaces namespace foo { union Bar { diff --git a/bindgen-tests/tests/headers/bitfield-enum-repr-c.hpp b/bindgen-tests/tests/headers/bitfield-enum-repr-c.hpp index 20a3f9dbbe..da5fc961dd 100644 --- a/bindgen-tests/tests/headers/bitfield-enum-repr-c.hpp +++ b/bindgen-tests/tests/headers/bitfield-enum-repr-c.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --bitfield-enum "Foo" --rust-target 1.27 -- -std=c++11 +// bindgen-flags: --bitfield-enum "Foo" -- -std=c++11 enum Foo { Bar = 1 << 1, diff --git a/bindgen-tests/tests/headers/bitfield-enum-repr-transparent.hpp b/bindgen-tests/tests/headers/bitfield-enum-repr-transparent.hpp index e53bb0753c..1c58ff4eca 100644 --- a/bindgen-tests/tests/headers/bitfield-enum-repr-transparent.hpp +++ b/bindgen-tests/tests/headers/bitfield-enum-repr-transparent.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --bitfield-enum "Foo" --rust-target 1.28 -- -std=c++11 +// bindgen-flags: --bitfield-enum "Foo" enum Foo { Bar = 1 << 1, diff --git a/bindgen-tests/tests/headers/bitfield-linux-32.hpp b/bindgen-tests/tests/headers/bitfield-linux-32.hpp index b9a480df15..71ee6a7e1d 100644 --- a/bindgen-tests/tests/headers/bitfield-linux-32.hpp +++ b/bindgen-tests/tests/headers/bitfield-linux-32.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: -- --target=i586-unknown-linux +// bindgen-flags: --no-layout-tests -- --target=i586-unknown-linux typedef unsigned long long uint64_t; diff --git a/bindgen-tests/tests/headers/bitfield-template.hpp b/bindgen-tests/tests/headers/bitfield-template.hpp new file mode 100644 index 0000000000..664199b9c0 --- /dev/null +++ b/bindgen-tests/tests/headers/bitfield-template.hpp @@ -0,0 +1,4 @@ +template struct foo { + T member; + bool b : 8; +}; diff --git a/bindgen-tests/tests/headers/bitfield_pack_offset.h b/bindgen-tests/tests/headers/bitfield_pack_offset.h new file mode 100644 index 0000000000..5118a64642 --- /dev/null +++ b/bindgen-tests/tests/headers/bitfield_pack_offset.h @@ -0,0 +1,21 @@ +struct A { + const unsigned char name[7]; /* 0 7 */ + unsigned char firmness:4; /* 7: 0 1 */ + unsigned char color:4; /* 7: 4 1 */ + unsigned short weedsBonus:3; /* 8: 0 2 */ + unsigned short pestsBonus:3; /* 8: 3 2 */ + unsigned short size:10; /* 8: 6 2 */ + unsigned char maxYield; /* 10 1 */ + unsigned char minYield:4; /* 11: 0 1 */ + unsigned char waterBonus:4; /* 11: 4 1 */ + + /* XXX 4 bytes hole, try to pack */ + + const unsigned char * description1; /* 16 8 */ + + /* size: 24, cachelines: 1, members: 10 */ + /* sum members: 16, holes: 1, sum holes: 4 */ + /* sum bitfield members: 32 bits (4 bytes) */ + /* last cacheline: 24 bytes */ +}; + diff --git a/bindgen-tests/tests/headers/char16_t.hpp b/bindgen-tests/tests/headers/char16_t.hpp new file mode 100644 index 0000000000..35e1f16dd3 --- /dev/null +++ b/bindgen-tests/tests/headers/char16_t.hpp @@ -0,0 +1,4 @@ +// bindgen-flags: --use-distinct-char16-t --raw-line '#[repr(transparent)] pub struct bindgen_cchar16_t(u16);' -- -x c++ -std=c++14 + +void receive_char16_t(char16_t input) { +} diff --git a/bindgen-tests/tests/headers/class.hpp b/bindgen-tests/tests/headers/class.hpp index a90e373f77..f77ac92a66 100644 --- a/bindgen-tests/tests/headers/class.hpp +++ b/bindgen-tests/tests/headers/class.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --with-derive-partialord --with-derive-ord --rust-target 1.40 +// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --with-derive-partialord --with-derive-ord // class C { int a; diff --git a/bindgen-tests/tests/headers/class_1_0.hpp b/bindgen-tests/tests/headers/class_1_0.hpp deleted file mode 100644 index e3735eb68d..0000000000 --- a/bindgen-tests/tests/headers/class_1_0.hpp +++ /dev/null @@ -1,76 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --impl-partialeq --with-derive-eq - -class C { - int a; - // More than rust limits (32) - char big_array[33]; -}; - -class C_with_zero_length_array { - int a; - // More than rust limits (32) - char big_array[33]; - char zero_length_array[0]; -}; - -class C_with_zero_length_array_2 { - int a; - char zero_length_array[0]; -}; - -class C_with_incomplete_array { - int a; - // More than rust limits (32) - char big_array[33]; - char incomplete_array[]; -}; - -class C_with_incomplete_array_2 { - int a; - char incomplete_array[]; -}; - - -class C_with_zero_length_array_and_incomplete_array { - int a; - // More than rust limits (32) - char big_array[33]; - char zero_length_array[0]; - char incomplete_array[]; -}; - -class C_with_zero_length_array_and_incomplete_array_2 { - int a; - char zero_length_array[0]; - char incomplete_array[]; -}; - - -class WithDtor { - int b; - - ~WithDtor() {} -}; - -class IncompleteArrayNonCopiable { - void* whatever; - C incomplete_array[]; -}; - -union Union { - float d; - int i; -}; - -class WithUnion { - Union data; -}; - -class RealAbstractionWithTonsOfMethods { - void foo(); -public: - void bar() const; - void bar(); - void bar(int foo); - static void sta(); -}; diff --git a/bindgen-tests/tests/headers/class_with_enum.hpp b/bindgen-tests/tests/headers/class_with_enum.hpp new file mode 100644 index 0000000000..ebbc2c4049 --- /dev/null +++ b/bindgen-tests/tests/headers/class_with_enum.hpp @@ -0,0 +1,7 @@ +class A { +public: + enum B { + B1, + B2, + }; +}; \ No newline at end of file diff --git a/bindgen-tests/tests/headers/class_with_inner_struct_1_0.hpp b/bindgen-tests/tests/headers/class_with_inner_struct_1_0.hpp deleted file mode 100644 index 34ed96e722..0000000000 --- a/bindgen-tests/tests/headers/class_with_inner_struct_1_0.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq --rustified-enum ".*" -// bindgen-flags: -- -std=c++11 - -class A { - unsigned c; - struct Segment { int begin, end; }; - union { - int f; - } named_union; - union { - int d; - }; -}; - -class B { - unsigned d; - struct Segment { int begin, end; }; -}; - - -enum class StepSyntax { - Keyword, // step-start and step-end - FunctionalWithoutKeyword, // steps(...) - FunctionalWithStartKeyword, // steps(..., start) - FunctionalWithEndKeyword, // steps(..., end) -}; - -class C { - unsigned d; - union { - struct { - float mX1; - float mY1; - float mX2; - float mY2; - } mFunc; - struct { - StepSyntax mStepSyntax; - unsigned int mSteps; - }; - }; - // To ensure it doesn't collide - struct Segment { int begin, end; }; -}; diff --git a/bindgen-tests/tests/headers/constify-module-enums-types.hpp b/bindgen-tests/tests/headers/constify-module-enums-types.hpp index decf935a00..96bed18f4b 100644 --- a/bindgen-tests/tests/headers/constify-module-enums-types.hpp +++ b/bindgen-tests/tests/headers/constify-module-enums-types.hpp @@ -1,5 +1,11 @@ // bindgen-flags: --constified-enum-module ".*" +using Uint = unsigned; +enum ExplicitTypeAlias : Uint { + SOME_CONSTANT, + SOME_OTHER_CONSTANT, +}; + typedef enum foo { THIS, SHOULD_BE, diff --git a/bindgen-tests/tests/headers/constructors_1_33.hpp b/bindgen-tests/tests/headers/constructors_1_33.hpp index e275f8907e..b16c8c35a3 100644 --- a/bindgen-tests/tests/headers/constructors_1_33.hpp +++ b/bindgen-tests/tests/headers/constructors_1_33.hpp @@ -1,5 +1,3 @@ -// bindgen-flags: --rust-target 1.33 - class TestOverload { // This one shouldn't be generated. TestOverload(); diff --git a/bindgen-tests/tests/headers/derive-bitfield-method-same-name.hpp b/bindgen-tests/tests/headers/derive-bitfield-method-same-name.hpp index ea9d801f4e..4b7b21e93a 100644 --- a/bindgen-tests/tests/headers/derive-bitfield-method-same-name.hpp +++ b/bindgen-tests/tests/headers/derive-bitfield-method-same-name.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --with-derive-partialeq --impl-partialeq --impl-debug --rust-target 1.40 +// bindgen-flags: --with-derive-partialeq --impl-partialeq --impl-debug /// Because this struct have array larger than 32 items /// and --with-derive-partialeq --impl-partialeq --impl-debug is provided, diff --git a/bindgen-tests/tests/headers/derive-clone.h b/bindgen-tests/tests/headers/derive-clone.h index aacbcaf885..8dc30eacfc 100644 --- a/bindgen-tests/tests/headers/derive-clone.h +++ b/bindgen-tests/tests/headers/derive-clone.h @@ -1,6 +1,3 @@ -// bindgen-flags: --rust-target 1.40 -// - /// This struct should derive `Clone`. struct ShouldDeriveClone { int large[33]; diff --git a/bindgen-tests/tests/headers/derive-clone_1_0.h b/bindgen-tests/tests/headers/derive-clone_1_0.h deleted file mode 100644 index 34ef40ae97..0000000000 --- a/bindgen-tests/tests/headers/derive-clone_1_0.h +++ /dev/null @@ -1,7 +0,0 @@ -// bindgen-flags: --rust-target 1.0 - -/// Since builtin `Clone` impls were introduced in Rust 1.21 this struct -/// should impl `Clone` "manually". -struct ShouldImplClone { - int large[33]; -}; diff --git a/bindgen-tests/tests/headers/derive-debug-bitfield-1-51.hpp b/bindgen-tests/tests/headers/derive-debug-bitfield-1-51.hpp new file mode 100644 index 0000000000..df43e6a7c2 --- /dev/null +++ b/bindgen-tests/tests/headers/derive-debug-bitfield-1-51.hpp @@ -0,0 +1,7 @@ +// bindgen-flags: --impl-debug + +class C { + bool a: 1; + bool b: 7; + int large_array[50]; +}; diff --git a/bindgen-tests/tests/headers/derive-debug-bitfield-core.hpp b/bindgen-tests/tests/headers/derive-debug-bitfield-core.hpp index 2073cc2a0d..5d78e74359 100644 --- a/bindgen-tests/tests/headers/derive-debug-bitfield-core.hpp +++ b/bindgen-tests/tests/headers/derive-debug-bitfield-core.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --impl-debug --use-core --raw-line "extern crate core;" --rust-target 1.40 +// bindgen-flags: --impl-debug --use-core --raw-line "extern crate core;" class C { bool a: 1; diff --git a/bindgen-tests/tests/headers/derive-debug-bitfield.hpp b/bindgen-tests/tests/headers/derive-debug-bitfield.hpp index b68919054a..df43e6a7c2 100644 --- a/bindgen-tests/tests/headers/derive-debug-bitfield.hpp +++ b/bindgen-tests/tests/headers/derive-debug-bitfield.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --impl-debug --rust-target 1.40 +// bindgen-flags: --impl-debug class C { bool a: 1; diff --git a/bindgen-tests/tests/headers/derive-debug-function-pointer.hpp b/bindgen-tests/tests/headers/derive-debug-function-pointer.hpp index 147097fbd8..a370dee813 100644 --- a/bindgen-tests/tests/headers/derive-debug-function-pointer.hpp +++ b/bindgen-tests/tests/headers/derive-debug-function-pointer.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --impl-debug --rust-target 1.40 +// bindgen-flags: --impl-debug class Nice { typedef void (*Function) (int data); diff --git a/bindgen-tests/tests/headers/derive-debug-generic.hpp b/bindgen-tests/tests/headers/derive-debug-generic.hpp index 50122fafa5..d5158510ea 100644 --- a/bindgen-tests/tests/headers/derive-debug-generic.hpp +++ b/bindgen-tests/tests/headers/derive-debug-generic.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --impl-debug --rust-target 1.40 +// bindgen-flags: --impl-debug template class Generic { diff --git a/bindgen-tests/tests/headers/derive-debug-opaque-template-instantiation.hpp b/bindgen-tests/tests/headers/derive-debug-opaque-template-instantiation.hpp index 0c70fcc53a..0dead782ff 100644 --- a/bindgen-tests/tests/headers/derive-debug-opaque-template-instantiation.hpp +++ b/bindgen-tests/tests/headers/derive-debug-opaque-template-instantiation.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --impl-debug --rust-target 1.40 +// bindgen-flags: --impl-debug // This type is opaque because the second template parameter // is a non-type template parameter diff --git a/bindgen-tests/tests/headers/derive-debug-opaque.hpp b/bindgen-tests/tests/headers/derive-debug-opaque.hpp index 715d3c89f1..0ce1d63ab8 100644 --- a/bindgen-tests/tests/headers/derive-debug-opaque.hpp +++ b/bindgen-tests/tests/headers/derive-debug-opaque.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --opaque-type "Opaque" --impl-debug --rust-target 1.40 +// bindgen-flags: --opaque-type "Opaque" --impl-debug class Opaque { int i; diff --git a/bindgen-tests/tests/headers/derive-partialeq-base.hpp b/bindgen-tests/tests/headers/derive-partialeq-base.hpp index 2a57dca47d..989cbe693a 100644 --- a/bindgen-tests/tests/headers/derive-partialeq-base.hpp +++ b/bindgen-tests/tests/headers/derive-partialeq-base.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --with-derive-partialeq --impl-partialeq --rust-target 1.40 +// bindgen-flags: --with-derive-partialeq --impl-partialeq class Base { int large[33]; diff --git a/bindgen-tests/tests/headers/derive-partialeq-bitfield.hpp b/bindgen-tests/tests/headers/derive-partialeq-bitfield.hpp index f6dd82e572..ac2cac632a 100644 --- a/bindgen-tests/tests/headers/derive-partialeq-bitfield.hpp +++ b/bindgen-tests/tests/headers/derive-partialeq-bitfield.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --with-derive-partialeq --impl-partialeq --rust-target 1.40 +// bindgen-flags: --with-derive-partialeq --impl-partialeq class C { bool a: 1; diff --git a/bindgen-tests/tests/headers/derive-partialeq-core.h b/bindgen-tests/tests/headers/derive-partialeq-core.h index 18eed8b324..6da5b786bc 100644 --- a/bindgen-tests/tests/headers/derive-partialeq-core.h +++ b/bindgen-tests/tests/headers/derive-partialeq-core.h @@ -1,4 +1,4 @@ -// bindgen-flags: --with-derive-partialeq --impl-partialeq --use-core --raw-line "extern crate core;" --rust-target 1.40 +// bindgen-flags: --with-derive-partialeq --impl-partialeq --use-core --raw-line "extern crate core;" struct C { int large_array[420]; diff --git a/bindgen-tests/tests/headers/derive-partialeq-union_1_0.hpp b/bindgen-tests/tests/headers/derive-partialeq-union_1_0.hpp deleted file mode 100644 index d546d77b10..0000000000 --- a/bindgen-tests/tests/headers/derive-partialeq-union_1_0.hpp +++ /dev/null @@ -1,7 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-partialeq --impl-partialeq - -/// This should manually derive PartialEq. -union ShouldDerivePartialEq { - char a[150]; - int b; -}; diff --git a/bindgen-tests/tests/headers/enum-doc-rusty-non-exhaustive.h b/bindgen-tests/tests/headers/enum-doc-rusty-non-exhaustive.h new file mode 100644 index 0000000000..b544a0c4fc --- /dev/null +++ b/bindgen-tests/tests/headers/enum-doc-rusty-non-exhaustive.h @@ -0,0 +1,3 @@ +// bindgen-flags: --rustified-non-exhaustive-enum B + +#include "enum-doc.h" diff --git a/bindgen-tests/tests/headers/extern-const-struct.h b/bindgen-tests/tests/headers/extern-const-struct.h index 1027127428..10006e8284 100644 --- a/bindgen-tests/tests/headers/extern-const-struct.h +++ b/bindgen-tests/tests/headers/extern-const-struct.h @@ -1,5 +1,3 @@ -// bindgen-flags: --rust-target 1.40 - struct nsFoo { float details[400]; }; diff --git a/bindgen-tests/tests/headers/extern-fn-block-attrs-many.h b/bindgen-tests/tests/headers/extern-fn-block-attrs-many.h new file mode 100644 index 0000000000..0de6eebb36 --- /dev/null +++ b/bindgen-tests/tests/headers/extern-fn-block-attrs-many.h @@ -0,0 +1,3 @@ +// bindgen-flags: --extern-fn-block-attrs '#[allow(dead_code)]' --extern-fn-block-attrs '#[cfg_attr(not(windows), link(wasm_import_module = "test-module"))]' + +void test_function(); \ No newline at end of file diff --git a/bindgen-tests/tests/headers/extern-fn-block-attrs-wasm.h b/bindgen-tests/tests/headers/extern-fn-block-attrs-wasm.h new file mode 100644 index 0000000000..2f475f1ed1 --- /dev/null +++ b/bindgen-tests/tests/headers/extern-fn-block-attrs-wasm.h @@ -0,0 +1,3 @@ +// bindgen-flags: --extern-fn-block-attrs '#[allow(dead_code)]' --wasm-import-module-name test-module + +void test_function(); \ No newline at end of file diff --git a/bindgen-tests/tests/headers/extern-fn-block-attrs.h b/bindgen-tests/tests/headers/extern-fn-block-attrs.h new file mode 100644 index 0000000000..26480e2ef0 --- /dev/null +++ b/bindgen-tests/tests/headers/extern-fn-block-attrs.h @@ -0,0 +1,3 @@ +// bindgen-flags: --extern-fn-block-attrs '#[allow(dead_code)]' + +void test_function(); \ No newline at end of file diff --git a/bindgen-tests/tests/headers/extern_blocks_post_1_82.h b/bindgen-tests/tests/headers/extern_blocks_post_1_82.h new file mode 100644 index 0000000000..f7f3464e98 --- /dev/null +++ b/bindgen-tests/tests/headers/extern_blocks_post_1_82.h @@ -0,0 +1,5 @@ +// bindgen-flags: --no-layout-tests --rust-target=1.82 + +void cool_function(int i, char c); + +static int cool_static; diff --git a/bindgen-tests/tests/headers/extern_blocks_pre_1_82.h b/bindgen-tests/tests/headers/extern_blocks_pre_1_82.h new file mode 100644 index 0000000000..604625a0a3 --- /dev/null +++ b/bindgen-tests/tests/headers/extern_blocks_pre_1_82.h @@ -0,0 +1,5 @@ +// bindgen-flags: --no-layout-tests + +void cool_function(int i, char c); + +static int cool_static; diff --git a/bindgen-tests/tests/headers/forward_declared_complex_types_1_0.hpp b/bindgen-tests/tests/headers/forward_declared_complex_types_1_0.hpp deleted file mode 100644 index ff6076fc43..0000000000 --- a/bindgen-tests/tests/headers/forward_declared_complex_types_1_0.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// bindgen-flags: --rust-target 1.0 - -struct Foo_empty {}; -struct Foo; - -struct Bar { - Foo *f; -}; - -void baz_struct(Foo* f); - -union Union; - -void baz_union(Union* u); - -class Quux; - -void baz_class(Quux* q); diff --git a/bindgen-tests/tests/headers/i128.h b/bindgen-tests/tests/headers/i128.h index 6ec399c726..1880f11305 100644 --- a/bindgen-tests/tests/headers/i128.h +++ b/bindgen-tests/tests/headers/i128.h @@ -1,5 +1,3 @@ -// bindgen-flags: --rust-target 1.26 - struct foo { __int128 my_signed; unsigned __int128 my_unsigned; diff --git a/bindgen-tests/tests/headers/infinite-macro.h b/bindgen-tests/tests/headers/infinite-macro.h deleted file mode 100644 index ab352c5785..0000000000 --- a/bindgen-tests/tests/headers/infinite-macro.h +++ /dev/null @@ -1,2 +0,0 @@ -#define INFINITY (1.0f/0.0f) -#define NAN (0.0f/0.0f) diff --git a/bindgen-tests/tests/headers/infinite-macro.hpp b/bindgen-tests/tests/headers/infinite-macro.hpp new file mode 100644 index 0000000000..32c8b61911 --- /dev/null +++ b/bindgen-tests/tests/headers/infinite-macro.hpp @@ -0,0 +1,7 @@ +#define INFINITY (1.0f/0.0f) +#define NEG_INFINITY (-1.0f/0.0f) +#define NAN (0.0f/0.0f) + +static const float F32_INFINITY = 1.0f / 0.0f; +static const float F32_NEG_INFINITY = -1.0f / 0.0f; +static const float F32_NAN = 0.0f / 0.0f; diff --git a/bindgen-tests/tests/headers/inline_namespace_macro.hpp b/bindgen-tests/tests/headers/inline_namespace_macro.hpp new file mode 100644 index 0000000000..c7cf5caf98 --- /dev/null +++ b/bindgen-tests/tests/headers/inline_namespace_macro.hpp @@ -0,0 +1,9 @@ +// bindgen-flags: --enable-cxx-namespaces -- -std=c++11 + +#include "namespace/nsdefine.h" + +BEGIN_NAMESPACE + +class duration {}; + +END_NAMESPACE diff --git a/bindgen-tests/tests/headers/issue-1291.hpp b/bindgen-tests/tests/headers/issue-1291.hpp index 4ec524f12f..cb4aeb91f8 100644 --- a/bindgen-tests/tests/headers/issue-1291.hpp +++ b/bindgen-tests/tests/headers/issue-1291.hpp @@ -1,4 +1,3 @@ -// bindgen-flags: --rust-target 1.25 // bindgen-unstable struct __attribute__((aligned(16))) RTCRay diff --git a/bindgen-tests/tests/headers/issue-2618.h b/bindgen-tests/tests/headers/issue-2618.h new file mode 100644 index 0000000000..841ff61d77 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-2618.h @@ -0,0 +1,18 @@ +// bindgen-flags: --allowlist-var "val[0-9]+" + +typedef __UINT32_TYPE__ uint32_t; +typedef __UINT64_TYPE__ uint64_t; + +static const uint32_t val1 = 0x7fffffff; +static const uint32_t val2 = 0x80000000; +static const uint32_t val3 = 0xffffffff; +static const uint64_t val4 = 0x7fffffffffffffff; +static const uint64_t val5 = 0x8000000000000000; +static const uint64_t val6 = 0xffffffffffffffff; + +static const uint32_t val7 = (0x7fffffff); +static const uint32_t val8 = (0x80000000); +static const uint32_t val9 = (0xffffffff); +static const uint64_t val10 = (0x7fffffffffffffff); +static const uint64_t val11 = (0x8000000000000000); +static const uint64_t val12 = (0xffffffffffffffff); diff --git a/bindgen-tests/tests/headers/issue-2966.h b/bindgen-tests/tests/headers/issue-2966.h new file mode 100644 index 0000000000..3f00dec65d --- /dev/null +++ b/bindgen-tests/tests/headers/issue-2966.h @@ -0,0 +1,6 @@ +// bindgen-flags: --default-alias-style=new_type +// bindgen-parse-callbacks: type-visibility + +typedef const char * pub_var1; +typedef const char * pubcrate_var2; +typedef const char * private_var3; diff --git a/bindgen-tests/tests/headers/issue-3027.hpp b/bindgen-tests/tests/headers/issue-3027.hpp new file mode 100644 index 0000000000..d9b87ee6e2 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-3027.hpp @@ -0,0 +1,6 @@ +// bindgen-flags: --enable-cxx-namespaces + +namespace regression { + template class A { char c[N]; }; + class C { A<3> a; }; +} diff --git a/bindgen-tests/tests/headers/issue-372.hpp b/bindgen-tests/tests/headers/issue-372.hpp index a2a5d45122..7127be2ccb 100644 --- a/bindgen-tests/tests/headers/issue-372.hpp +++ b/bindgen-tests/tests/headers/issue-372.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --enable-cxx-namespaces --rustified-enum ".*" --rust-target 1.40 +// bindgen-flags: --enable-cxx-namespaces --rustified-enum ".*" template class c { a e[b]; }; class d; template class C { c h; }; diff --git a/bindgen-tests/tests/headers/issue-493_1_0.hpp b/bindgen-tests/tests/headers/issue-493_1_0.hpp deleted file mode 100644 index af6fd47c41..0000000000 --- a/bindgen-tests/tests/headers/issue-493_1_0.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq --rustified-enum ".*" - -template -class basic_string -{ -public: - typedef unsigned long long size_type; - typedef char value_type; - typedef value_type * pointer; - - struct __long - { - size_type __cap_; - size_type __size_; - pointer __data_; - }; - - enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ? - (sizeof(__long) - 1)/sizeof(value_type) : 2}; - - struct __short - { - union - { - unsigned char __size_; - value_type __lx; - }; - value_type __data_[__min_cap]; - }; - - union __ulx{__long __lx; __short __lxx;}; - - enum {__n_words = sizeof(__ulx) / sizeof(size_type)}; - - struct __raw - { - size_type __words[__n_words]; - }; - - struct __rep - { - union - { - __long __l; - __short __s; - __raw __r; - }; - }; -}; diff --git a/bindgen-tests/tests/headers/issue-537-repr-packed-n.h b/bindgen-tests/tests/headers/issue-537-repr-packed-n.h index 7beaf88383..40be004c85 100644 --- a/bindgen-tests/tests/headers/issue-537-repr-packed-n.h +++ b/bindgen-tests/tests/headers/issue-537-repr-packed-n.h @@ -1,4 +1,4 @@ -// bindgen-flags: --raw-line '#![cfg(feature = "nightly")]' --rust-target 1.33 +// bindgen-flags: --raw-line '#![cfg(feature = "nightly")]' /// This should not be opaque; we can see the attributes and can pack the /// struct. diff --git a/bindgen-tests/tests/headers/issue-648-derive-debug-with-padding.h b/bindgen-tests/tests/headers/issue-648-derive-debug-with-padding.h index 0860ce9502..d54fe374ce 100644 --- a/bindgen-tests/tests/headers/issue-648-derive-debug-with-padding.h +++ b/bindgen-tests/tests/headers/issue-648-derive-debug-with-padding.h @@ -1,4 +1,4 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq --rust-target 1.40 +// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq /** * We emit a `[u8; 63usize]` padding field for this struct, which cannot derive * Debug/Hash because 63 is over the hard coded limit. diff --git a/bindgen-tests/tests/headers/issue-743.h b/bindgen-tests/tests/headers/issue-743.h new file mode 100644 index 0000000000..1f8e0ccd78 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-743.h @@ -0,0 +1,6 @@ + +struct S { + void *p; + _Bool b; + unsigned u : 16; +}; \ No newline at end of file diff --git a/bindgen-tests/tests/headers/jsval_layout_opaque_1_0.hpp b/bindgen-tests/tests/headers/jsval_layout_opaque_1_0.hpp deleted file mode 100644 index c8e665516b..0000000000 --- a/bindgen-tests/tests/headers/jsval_layout_opaque_1_0.hpp +++ /dev/null @@ -1,425 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq --rustified-enum ".*" -// bindgen-flags: -- -std=c++11 - -/** - * These typedefs are hacky, but keep our tests consistent across 64-bit - * platforms, otherwise the id's change and our CI is unhappy. - */ -typedef unsigned char uint8_t; -typedef int int32_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -typedef unsigned long long size_t; -typedef unsigned long long uintptr_t; - - -#define JS_PUNBOX64 -#define IS_LITTLE_ENDIAN - -/* - * Try to get jsvals 64-bit aligned. We could almost assert that all values are - * aligned, but MSVC and GCC occasionally break alignment. - */ -#if defined(__GNUC__) || defined(__xlc__) || defined(__xlC__) -# define JSVAL_ALIGNMENT __attribute__((aligned (8))) -#elif defined(_MSC_VER) - /* - * Structs can be aligned with MSVC, but not if they are used as parameters, - * so we just don't try to align. - */ -# define JSVAL_ALIGNMENT -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# define JSVAL_ALIGNMENT -#elif defined(__HP_cc) || defined(__HP_aCC) -# define JSVAL_ALIGNMENT -#endif - -#if defined(JS_PUNBOX64) -# define JSVAL_TAG_SHIFT 47 -#endif - -/* - * We try to use enums so that printing a jsval_layout in the debugger shows - * nice symbolic type tags, however we can only do this when we can force the - * underlying type of the enum to be the desired size. - */ -#if !defined(__SUNPRO_CC) && !defined(__xlC__) - -#if defined(_MSC_VER) -# define JS_ENUM_HEADER(id, type) enum id : type -# define JS_ENUM_FOOTER(id) -#else -# define JS_ENUM_HEADER(id, type) enum id -# define JS_ENUM_FOOTER(id) __attribute__((packed)) -#endif - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueType, uint8_t) -{ - JSVAL_TYPE_DOUBLE = 0x00, - JSVAL_TYPE_INT32 = 0x01, - JSVAL_TYPE_UNDEFINED = 0x02, - JSVAL_TYPE_BOOLEAN = 0x03, - JSVAL_TYPE_MAGIC = 0x04, - JSVAL_TYPE_STRING = 0x05, - JSVAL_TYPE_SYMBOL = 0x06, - JSVAL_TYPE_NULL = 0x07, - JSVAL_TYPE_OBJECT = 0x08, - - /* These never appear in a jsval; they are only provided as an out-of-band value. */ - JSVAL_TYPE_UNKNOWN = 0x20, - JSVAL_TYPE_MISSING = 0x21 -} JS_ENUM_FOOTER(JSValueType); - -static_assert(sizeof(JSValueType) == 1, - "compiler typed enum support is apparently buggy"); - -#if defined(JS_NUNBOX32) - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueTag, uint32_t) -{ - JSVAL_TAG_CLEAR = 0xFFFFFF80, - JSVAL_TAG_INT32 = JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32, - JSVAL_TAG_UNDEFINED = JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED, - JSVAL_TAG_STRING = JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING, - JSVAL_TAG_SYMBOL = JSVAL_TAG_CLEAR | JSVAL_TYPE_SYMBOL, - JSVAL_TAG_BOOLEAN = JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN, - JSVAL_TAG_MAGIC = JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC, - JSVAL_TAG_NULL = JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL, - JSVAL_TAG_OBJECT = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT -} JS_ENUM_FOOTER(JSValueTag); - -static_assert(sizeof(JSValueTag) == sizeof(uint32_t), - "compiler typed enum support is apparently buggy"); - -#elif defined(JS_PUNBOX64) - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueTag, uint32_t) -{ - JSVAL_TAG_MAX_DOUBLE = 0x1FFF0, - JSVAL_TAG_INT32 = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32, - JSVAL_TAG_UNDEFINED = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED, - JSVAL_TAG_STRING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING, - JSVAL_TAG_SYMBOL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_SYMBOL, - JSVAL_TAG_BOOLEAN = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN, - JSVAL_TAG_MAGIC = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC, - JSVAL_TAG_NULL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL, - JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT -} JS_ENUM_FOOTER(JSValueTag); - -static_assert(sizeof(JSValueTag) == sizeof(uint32_t), - "compiler typed enum support is apparently buggy"); - -JS_ENUM_HEADER(JSValueShiftedTag, uint64_t) -{ - JSVAL_SHIFTED_TAG_MAX_DOUBLE = ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF), - JSVAL_SHIFTED_TAG_INT32 = (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_UNDEFINED = (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_STRING = (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_SYMBOL = (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_BOOLEAN = (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_MAGIC = (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_NULL = (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_OBJECT = (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) -} JS_ENUM_FOOTER(JSValueShiftedTag); - -static_assert(sizeof(JSValueShiftedTag) == sizeof(uint64_t), - "compiler typed enum support is apparently buggy"); - -#endif - -/* - * All our supported compilers implement C++11 |enum Foo : T| syntax, so don't - * expose these macros. (This macro exists *only* because gcc bug 51242 - * makes bit-fields of - * typed enums trigger a warning that can't be turned off. Don't expose it - * beyond this file!) - */ -#undef JS_ENUM_HEADER -#undef JS_ENUM_FOOTER - -#else /* !defined(__SUNPRO_CC) && !defined(__xlC__) */ - -typedef uint8_t JSValueType; -#define JSVAL_TYPE_DOUBLE ((uint8_t)0x00) -#define JSVAL_TYPE_INT32 ((uint8_t)0x01) -#define JSVAL_TYPE_UNDEFINED ((uint8_t)0x02) -#define JSVAL_TYPE_BOOLEAN ((uint8_t)0x03) -#define JSVAL_TYPE_MAGIC ((uint8_t)0x04) -#define JSVAL_TYPE_STRING ((uint8_t)0x05) -#define JSVAL_TYPE_SYMBOL ((uint8_t)0x06) -#define JSVAL_TYPE_NULL ((uint8_t)0x07) -#define JSVAL_TYPE_OBJECT ((uint8_t)0x08) -#define JSVAL_TYPE_UNKNOWN ((uint8_t)0x20) - -#if defined(JS_NUNBOX32) - -typedef uint32_t JSValueTag; -#define JSVAL_TAG_CLEAR ((uint32_t)(0xFFFFFF80)) -#define JSVAL_TAG_INT32 ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32)) -#define JSVAL_TAG_UNDEFINED ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED)) -#define JSVAL_TAG_STRING ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING)) -#define JSVAL_TAG_SYMBOL ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_SYMBOL)) -#define JSVAL_TAG_BOOLEAN ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN)) -#define JSVAL_TAG_MAGIC ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC)) -#define JSVAL_TAG_NULL ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL)) -#define JSVAL_TAG_OBJECT ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT)) - -#elif defined(JS_PUNBOX64) - -typedef uint32_t JSValueTag; -#define JSVAL_TAG_MAX_DOUBLE ((uint32_t)(0x1FFF0)) -#define JSVAL_TAG_INT32 (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32) -#define JSVAL_TAG_UNDEFINED (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED) -#define JSVAL_TAG_STRING (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING) -#define JSVAL_TAG_SYMBOL (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_SYMBOL) -#define JSVAL_TAG_BOOLEAN (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN) -#define JSVAL_TAG_MAGIC (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC) -#define JSVAL_TAG_NULL (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL) -#define JSVAL_TAG_OBJECT (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT) - -typedef uint64_t JSValueShiftedTag; -#define JSVAL_SHIFTED_TAG_MAX_DOUBLE ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF) -#define JSVAL_SHIFTED_TAG_INT32 (((uint64_t)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_UNDEFINED (((uint64_t)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_STRING (((uint64_t)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_SYMBOL (((uint64_t)JSVAL_TAG_SYMBOL) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_BOOLEAN (((uint64_t)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_MAGIC (((uint64_t)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_NULL (((uint64_t)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_OBJECT (((uint64_t)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) - -#endif /* JS_PUNBOX64 */ -#endif /* !defined(__SUNPRO_CC) && !defined(__xlC__) */ - -#if defined(JS_NUNBOX32) - -#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_CLEAR | (type))) - -#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL -#define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT -#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32 -#define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING - -#elif defined(JS_PUNBOX64) - -#define JSVAL_PAYLOAD_MASK 0x00007FFFFFFFFFFFLL -#define JSVAL_TAG_MASK 0xFFFF800000000000LL -#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type))) -#define JSVAL_TYPE_TO_SHIFTED_TAG(type) (((uint64_t)JSVAL_TYPE_TO_TAG(type)) << JSVAL_TAG_SHIFT) - -#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL -#define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT -#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32 -#define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING - -#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET JSVAL_SHIFTED_TAG_NULL -#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET JSVAL_SHIFTED_TAG_OBJECT -#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET JSVAL_SHIFTED_TAG_UNDEFINED -#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET JSVAL_SHIFTED_TAG_STRING - -#endif /* JS_PUNBOX64 */ - -typedef enum JSWhyMagic -{ - /** a hole in a native object's elements */ - JS_ELEMENTS_HOLE, - - /** there is not a pending iterator value */ - JS_NO_ITER_VALUE, - - /** exception value thrown when closing a generator */ - JS_GENERATOR_CLOSING, - - /** compiler sentinel value */ - JS_NO_CONSTANT, - - /** used in debug builds to catch tracing errors */ - JS_THIS_POISON, - - /** used in debug builds to catch tracing errors */ - JS_ARG_POISON, - - /** an empty subnode in the AST serializer */ - JS_SERIALIZE_NO_NODE, - - /** lazy arguments value on the stack */ - JS_LAZY_ARGUMENTS, - - /** optimized-away 'arguments' value */ - JS_OPTIMIZED_ARGUMENTS, - - /** magic value passed to natives to indicate construction */ - JS_IS_CONSTRUCTING, - - /** arguments.callee has been overwritten */ - JS_OVERWRITTEN_CALLEE, - - /** value of static block object slot */ - JS_BLOCK_NEEDS_CLONE, - - /** see class js::HashableValue */ - JS_HASH_KEY_EMPTY, - - /** error while running Ion code */ - JS_ION_ERROR, - - /** missing recover instruction result */ - JS_ION_BAILOUT, - - /** optimized out slot */ - JS_OPTIMIZED_OUT, - - /** uninitialized lexical bindings that produce ReferenceError on touch. */ - JS_UNINITIALIZED_LEXICAL, - - /** for local use */ - JS_GENERIC_MAGIC, - - JS_WHY_MAGIC_COUNT -} JSWhyMagic; - -#if defined(IS_LITTLE_ENDIAN) -# if defined(JS_NUNBOX32) -typedef union jsval_layout -{ - uint64_t asBits; - struct { - union { - int32_t i32; - uint32_t u32; - uint32_t boo; // Don't use |bool| -- it must be four bytes. - JSString* str; - JS::Symbol* sym; - JSObject* obj; - js::gc::Cell* cell; - void* ptr; - JSWhyMagic why; - size_t word; - uintptr_t uintptr; - } payload; - JSValueTag tag; - } s; - double asDouble; - void* asPtr; -} JSVAL_ALIGNMENT jsval_layout; -# elif defined(JS_PUNBOX64) -typedef union jsval_layout -{ - uint64_t asBits; -#if !defined(_WIN64) - /* MSVC does not pack these correctly :-( */ - struct { - uint64_t payload47 : 47; - JSValueTag tag : 17; - } debugView; -#endif - struct { - union { - int32_t i32; - uint32_t u32; - JSWhyMagic why; - } payload; - } s; - double asDouble; - void* asPtr; - size_t asWord; - uintptr_t asUIntPtr; -} JSVAL_ALIGNMENT jsval_layout; -# endif /* JS_PUNBOX64 */ -#else /* defined(IS_LITTLE_ENDIAN) */ -# if defined(JS_NUNBOX32) -typedef union jsval_layout -{ - uint64_t asBits; - struct { - JSValueTag tag; - union { - int32_t i32; - uint32_t u32; - uint32_t boo; // Don't use |bool| -- it must be four bytes. - JSString* str; - JS::Symbol* sym; - JSObject* obj; - js::gc::Cell* cell; - void* ptr; - JSWhyMagic why; - size_t word; - uintptr_t uintptr; - } payload; - } s; - double asDouble; - void* asPtr; -} JSVAL_ALIGNMENT jsval_layout; -# elif defined(JS_PUNBOX64) -typedef union jsval_layout -{ - uint64_t asBits; - struct { - JSValueTag tag : 17; - uint64_t payload47 : 47; - } debugView; - struct { - uint32_t padding; - union { - int32_t i32; - uint32_t u32; - JSWhyMagic why; - } payload; - } s; - double asDouble; - void* asPtr; - size_t asWord; - uintptr_t asUIntPtr; -} JSVAL_ALIGNMENT jsval_layout; -# endif /* JS_PUNBOX64 */ -#endif /* defined(IS_LITTLE_ENDIAN) */ - -/* - * For codesize purposes on some platforms, it's important that the - * compiler know that JS::Values constructed from constant values can be - * folded to constant bit patterns at compile time, rather than - * constructed at runtime. Doing this requires a fair amount of C++11 - * features, which are not supported on all of our compilers. Set up - * some defines and helper macros in an attempt to confine the ugliness - * here, rather than scattering it all about the file. The important - * features are: - * - * - constexpr; - * - defaulted functions; - * - C99-style designated initializers. - */ -#if defined(__clang__) -# if __has_feature(cxx_constexpr) && __has_feature(cxx_defaulted_functions) -# define JS_VALUE_IS_CONSTEXPR -# endif -#elif defined(__GNUC__) -/* - * We need 4.5 for defaulted functions, 4.6 for constexpr, 4.7 because 4.6 - * doesn't understand |(X) { .field = ... }| syntax, and 4.7.3 because - * versions prior to that have bugs in the C++ front-end that cause crashes. - */ -# if MOZ_GCC_VERSION_AT_LEAST(4, 7, 3) -# define JS_VALUE_IS_CONSTEXPR -# endif -#endif - -#if defined(JS_VALUE_IS_CONSTEXPR) -# define JS_RETURN_LAYOUT_FROM_BITS(BITS) \ - return (jsval_layout) { .asBits = (BITS) } -# define JS_VALUE_CONSTEXPR MOZ_CONSTEXPR -# define JS_VALUE_CONSTEXPR_VAR MOZ_CONSTEXPR_VAR -#else -# define JS_RETURN_LAYOUT_FROM_BITS(BITS) \ - jsval_layout l; \ - l.asBits = (BITS); \ - return l; -# define JS_VALUE_CONSTEXPR -# define JS_VALUE_CONSTEXPR_VAR const -#endif - -struct Value { - jsval_layout data; -}; diff --git a/bindgen-tests/tests/headers/keywords.h b/bindgen-tests/tests/headers/keywords.h index 3b3fc4976e..49924193c7 100644 --- a/bindgen-tests/tests/headers/keywords.h +++ b/bindgen-tests/tests/headers/keywords.h @@ -21,6 +21,7 @@ int box; int crate; int false; int fn; +int gen; int impl; int in; int let; diff --git a/bindgen-tests/tests/headers/layout.h b/bindgen-tests/tests/headers/layout.h index b290ee856b..06b7165ab9 100644 --- a/bindgen-tests/tests/headers/layout.h +++ b/bindgen-tests/tests/headers/layout.h @@ -1,10 +1,11 @@ -// bindgen-flags: --rust-target 1.21 -// // FIXME: https://github.com/rust-lang/rust-bindgen/issues/1498 + +#if 0 struct header { char proto; unsigned int size __attribute__ ((packed)); unsigned char data[] __attribute__ ((aligned(8))); } __attribute__ ((aligned, packed)); +#endif diff --git a/bindgen-tests/tests/headers/layout_array.h b/bindgen-tests/tests/headers/layout_array.h index e6a57f7ca4..239e52b193 100644 --- a/bindgen-tests/tests/headers/layout_array.h +++ b/bindgen-tests/tests/headers/layout_array.h @@ -1,4 +1,4 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq --rust-target 1.40 +// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; diff --git a/bindgen-tests/tests/headers/layout_array_too_long.h b/bindgen-tests/tests/headers/layout_array_too_long.h index 53e4d8bed4..d0d34ba038 100644 --- a/bindgen-tests/tests/headers/layout_array_too_long.h +++ b/bindgen-tests/tests/headers/layout_array_too_long.h @@ -1,4 +1,4 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq --rustified-enum ".*" --rust-target 1.40 +// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq --rustified-enum ".*" typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; diff --git a/bindgen-tests/tests/headers/layout_eth_conf.h b/bindgen-tests/tests/headers/layout_eth_conf.h index 1c821c9769..ec1a691985 100644 --- a/bindgen-tests/tests/headers/layout_eth_conf.h +++ b/bindgen-tests/tests/headers/layout_eth_conf.h @@ -1,4 +1,4 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --rustified-enum ".*" --rust-target 1.40 +// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --rustified-enum ".*" typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; diff --git a/bindgen-tests/tests/headers/layout_eth_conf_1_0.h b/bindgen-tests/tests/headers/layout_eth_conf_1_0.h deleted file mode 100644 index 7da582ba19..0000000000 --- a/bindgen-tests/tests/headers/layout_eth_conf_1_0.h +++ /dev/null @@ -1,429 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq --rustified-enum ".*" - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; - -/** - * Simple flags are used for rte_eth_conf.rxmode.mq_mode. - */ -#define ETH_MQ_RX_RSS_FLAG 0x1 -#define ETH_MQ_RX_DCB_FLAG 0x2 -#define ETH_MQ_RX_VMDQ_FLAG 0x4 - -/* Definitions used for VMDQ and DCB functionality */ -#define ETH_VMDQ_MAX_VLAN_FILTERS 64 /**< Maximum nb. of VMDQ vlan filters. */ -#define ETH_DCB_NUM_USER_PRIORITIES 8 /**< Maximum nb. of DCB priorities. */ -#define ETH_VMDQ_DCB_NUM_QUEUES 128 /**< Maximum nb. of VMDQ DCB queues. */ -#define ETH_DCB_NUM_QUEUES 128 /**< Maximum nb. of DCB queues. */ - -/** - * A set of values to identify what method is to be used to route - * packets to multiple queues. - */ -enum rte_eth_rx_mq_mode { - /** None of DCB,RSS or VMDQ mode */ - ETH_MQ_RX_NONE = 0, - - /** For RX side, only RSS is on */ - ETH_MQ_RX_RSS = ETH_MQ_RX_RSS_FLAG, - /** For RX side,only DCB is on. */ - ETH_MQ_RX_DCB = ETH_MQ_RX_DCB_FLAG, - /** Both DCB and RSS enable */ - ETH_MQ_RX_DCB_RSS = ETH_MQ_RX_RSS_FLAG | ETH_MQ_RX_DCB_FLAG, - - /** Only VMDQ, no RSS nor DCB */ - ETH_MQ_RX_VMDQ_ONLY = ETH_MQ_RX_VMDQ_FLAG, - /** RSS mode with VMDQ */ - ETH_MQ_RX_VMDQ_RSS = ETH_MQ_RX_RSS_FLAG | ETH_MQ_RX_VMDQ_FLAG, - /** Use VMDQ+DCB to route traffic to queues */ - ETH_MQ_RX_VMDQ_DCB = ETH_MQ_RX_VMDQ_FLAG | ETH_MQ_RX_DCB_FLAG, - /** Enable both VMDQ and DCB in VMDq */ - ETH_MQ_RX_VMDQ_DCB_RSS = ETH_MQ_RX_RSS_FLAG | ETH_MQ_RX_DCB_FLAG | - ETH_MQ_RX_VMDQ_FLAG, -}; - -/** - * A structure used to configure the RX features of an Ethernet port. - */ -struct rte_eth_rxmode { - /** The multi-queue packet distribution mode to be used, e.g. RSS. */ - enum rte_eth_rx_mq_mode mq_mode; - uint32_t max_rx_pkt_len; /**< Only used if jumbo_frame enabled. */ - uint16_t split_hdr_size; /**< hdr buf size (header_split enabled).*/ - __extension__ - uint16_t header_split : 1, /**< Header Split enable. */ - hw_ip_checksum : 1, /**< IP/UDP/TCP checksum offload enable. */ - hw_vlan_filter : 1, /**< VLAN filter enable. */ - hw_vlan_strip : 1, /**< VLAN strip enable. */ - hw_vlan_extend : 1, /**< Extended VLAN enable. */ - jumbo_frame : 1, /**< Jumbo Frame Receipt enable. */ - hw_strip_crc : 1, /**< Enable CRC stripping by hardware. */ - enable_scatter : 1, /**< Enable scatter packets rx handler */ - enable_lro : 1; /**< Enable LRO */ -}; - -/** - * A set of values to identify what method is to be used to transmit - * packets using multi-TCs. - */ -enum rte_eth_tx_mq_mode { - ETH_MQ_TX_NONE = 0, /**< It is in neither DCB nor VT mode. */ - ETH_MQ_TX_DCB, /**< For TX side,only DCB is on. */ - ETH_MQ_TX_VMDQ_DCB, /**< For TX side,both DCB and VT is on. */ - ETH_MQ_TX_VMDQ_ONLY, /**< Only VT on, no DCB */ -}; - -/** - * A structure used to configure the TX features of an Ethernet port. - */ -struct rte_eth_txmode { - enum rte_eth_tx_mq_mode mq_mode; /**< TX multi-queues mode. */ - - /* For i40e specifically */ - uint16_t pvid; - __extension__ - uint8_t hw_vlan_reject_tagged : 1, - /**< If set, reject sending out tagged pkts */ - hw_vlan_reject_untagged : 1, - /**< If set, reject sending out untagged pkts */ - hw_vlan_insert_pvid : 1; - /**< If set, enable port based VLAN insertion */ -}; - -/** - * A structure used to configure the Receive Side Scaling (RSS) feature - * of an Ethernet port. - * If not NULL, the *rss_key* pointer of the *rss_conf* structure points - * to an array holding the RSS key to use for hashing specific header - * fields of received packets. The length of this array should be indicated - * by *rss_key_len* below. Otherwise, a default random hash key is used by - * the device driver. - * - * The *rss_key_len* field of the *rss_conf* structure indicates the length - * in bytes of the array pointed by *rss_key*. To be compatible, this length - * will be checked in i40e only. Others assume 40 bytes to be used as before. - * - * The *rss_hf* field of the *rss_conf* structure indicates the different - * types of IPv4/IPv6 packets to which the RSS hashing must be applied. - * Supplying an *rss_hf* equal to zero disables the RSS feature. - */ -struct rte_eth_rss_conf { - uint8_t *rss_key; /**< If not NULL, 40-byte hash key. */ - uint8_t rss_key_len; /**< hash key length in bytes. */ - uint64_t rss_hf; /**< Hash functions to apply - see below. */ -}; - -/** - * This enum indicates the possible number of traffic classes - * in DCB configratioins - */ -enum rte_eth_nb_tcs { - ETH_4_TCS = 4, /**< 4 TCs with DCB. */ - ETH_8_TCS = 8 /**< 8 TCs with DCB. */ -}; - -/** - * This enum indicates the possible number of queue pools - * in VMDQ configurations. - */ -enum rte_eth_nb_pools { - ETH_8_POOLS = 8, /**< 8 VMDq pools. */ - ETH_16_POOLS = 16, /**< 16 VMDq pools. */ - ETH_32_POOLS = 32, /**< 32 VMDq pools. */ - ETH_64_POOLS = 64 /**< 64 VMDq pools. */ -}; - -/** - * A structure used to configure the VMDQ+DCB feature - * of an Ethernet port. - * - * Using this feature, packets are routed to a pool of queues, based - * on the vlan ID in the vlan tag, and then to a specific queue within - * that pool, using the user priority vlan tag field. - * - * A default pool may be used, if desired, to route all traffic which - * does not match the vlan filter rules. - */ -struct rte_eth_vmdq_dcb_conf { - enum rte_eth_nb_pools nb_queue_pools; /**< With DCB, 16 or 32 pools */ - uint8_t enable_default_pool; /**< If non-zero, use a default pool */ - uint8_t default_pool; /**< The default pool, if applicable */ - uint8_t nb_pool_maps; /**< We can have up to 64 filters/mappings */ - struct { - uint16_t vlan_id; /**< The vlan ID of the received frame */ - uint64_t pools; /**< Bitmask of pools for packet rx */ - } pool_map[ETH_VMDQ_MAX_VLAN_FILTERS]; /**< VMDq vlan pool maps. */ - uint8_t dcb_tc[ETH_DCB_NUM_USER_PRIORITIES]; - /**< Selects a queue in a pool */ -}; - -/* This structure may be extended in future. */ -struct rte_eth_dcb_rx_conf { - enum rte_eth_nb_tcs nb_tcs; /**< Possible DCB TCs, 4 or 8 TCs */ - /** Traffic class each UP mapped to. */ - uint8_t dcb_tc[ETH_DCB_NUM_USER_PRIORITIES]; -}; - -struct rte_eth_vmdq_dcb_tx_conf { - enum rte_eth_nb_pools nb_queue_pools; /**< With DCB, 16 or 32 pools. */ - /** Traffic class each UP mapped to. */ - uint8_t dcb_tc[ETH_DCB_NUM_USER_PRIORITIES]; -}; - -struct rte_eth_dcb_tx_conf { - enum rte_eth_nb_tcs nb_tcs; /**< Possible DCB TCs, 4 or 8 TCs. */ - /** Traffic class each UP mapped to. */ - uint8_t dcb_tc[ETH_DCB_NUM_USER_PRIORITIES]; -}; - -struct rte_eth_vmdq_tx_conf { - enum rte_eth_nb_pools nb_queue_pools; /**< VMDq mode, 64 pools. */ -}; - -struct rte_eth_vmdq_rx_conf { - enum rte_eth_nb_pools nb_queue_pools; /**< VMDq only mode, 8 or 64 pools */ - uint8_t enable_default_pool; /**< If non-zero, use a default pool */ - uint8_t default_pool; /**< The default pool, if applicable */ - uint8_t enable_loop_back; /**< Enable VT loop back */ - uint8_t nb_pool_maps; /**< We can have up to 64 filters/mappings */ - uint32_t rx_mode; /**< Flags from ETH_VMDQ_ACCEPT_* */ - struct { - uint16_t vlan_id; /**< The vlan ID of the received frame */ - uint64_t pools; /**< Bitmask of pools for packet rx */ - } pool_map[ETH_VMDQ_MAX_VLAN_FILTERS]; /**< VMDq vlan pool maps. */ -}; - -/** - * Flow Director setting modes: none, signature or perfect. - */ -enum rte_fdir_mode { - RTE_FDIR_MODE_NONE = 0, /**< Disable FDIR support. */ - RTE_FDIR_MODE_SIGNATURE, /**< Enable FDIR signature filter mode. */ - RTE_FDIR_MODE_PERFECT, /**< Enable FDIR perfect filter mode. */ - RTE_FDIR_MODE_PERFECT_MAC_VLAN, /**< Enable FDIR filter mode - MAC VLAN. */ - RTE_FDIR_MODE_PERFECT_TUNNEL, /**< Enable FDIR filter mode - tunnel. */ -}; - -/** - * Memory space that can be configured to store Flow Director filters - * in the board memory. - */ -enum rte_fdir_pballoc_type { - RTE_FDIR_PBALLOC_64K = 0, /**< 64k. */ - RTE_FDIR_PBALLOC_128K, /**< 128k. */ - RTE_FDIR_PBALLOC_256K, /**< 256k. */ -}; - -/** - * Select report mode of FDIR hash information in RX descriptors. - */ -enum rte_fdir_status_mode { - RTE_FDIR_NO_REPORT_STATUS = 0, /**< Never report FDIR hash. */ - RTE_FDIR_REPORT_STATUS, /**< Only report FDIR hash for matching pkts. */ - RTE_FDIR_REPORT_STATUS_ALWAYS, /**< Always report FDIR hash. */ -}; - -/** - * A structure used to define the input for IPV4 flow - */ -struct rte_eth_ipv4_flow { - uint32_t src_ip; /**< IPv4 source address in big endian. */ - uint32_t dst_ip; /**< IPv4 destination address in big endian. */ - uint8_t tos; /**< Type of service to match. */ - uint8_t ttl; /**< Time to live to match. */ - uint8_t proto; /**< Protocol, next header in big endian. */ -}; - -/** - * A structure used to define the input for IPV6 flow - */ -struct rte_eth_ipv6_flow { - uint32_t src_ip[4]; /**< IPv6 source address in big endian. */ - uint32_t dst_ip[4]; /**< IPv6 destination address in big endian. */ - uint8_t tc; /**< Traffic class to match. */ - uint8_t proto; /**< Protocol, next header to match. */ - uint8_t hop_limits; /**< Hop limits to match. */ -}; - -/** - * A structure used to configure FDIR masks that are used by the device - * to match the various fields of RX packet headers. - */ -struct rte_eth_fdir_masks { - uint16_t vlan_tci_mask; /**< Bit mask for vlan_tci in big endian */ - /** Bit mask for ipv4 flow in big endian. */ - struct rte_eth_ipv4_flow ipv4_mask; - /** Bit maks for ipv6 flow in big endian. */ - struct rte_eth_ipv6_flow ipv6_mask; - /** Bit mask for L4 source port in big endian. */ - uint16_t src_port_mask; - /** Bit mask for L4 destination port in big endian. */ - uint16_t dst_port_mask; - /** 6 bit mask for proper 6 bytes of Mac address, bit 0 matches the - first byte on the wire */ - uint8_t mac_addr_byte_mask; - /** Bit mask for tunnel ID in big endian. */ - uint32_t tunnel_id_mask; - uint8_t tunnel_type_mask; /**< 1 - Match tunnel type, - 0 - Ignore tunnel type. */ -}; - -/** - * Payload type - */ -enum rte_eth_payload_type { - RTE_ETH_PAYLOAD_UNKNOWN = 0, - RTE_ETH_RAW_PAYLOAD, - RTE_ETH_L2_PAYLOAD, - RTE_ETH_L3_PAYLOAD, - RTE_ETH_L4_PAYLOAD, - RTE_ETH_PAYLOAD_MAX = 8, -}; - -#define RTE_ETH_FDIR_MAX_FLEXLEN 16 /**< Max length of flexbytes. */ -#define RTE_ETH_INSET_SIZE_MAX 128 /**< Max length of input set. */ - -/** - * A structure used to select bytes extracted from the protocol layers to - * flexible payload for filter - */ -struct rte_eth_flex_payload_cfg { - enum rte_eth_payload_type type; /**< Payload type */ - uint16_t src_offset[RTE_ETH_FDIR_MAX_FLEXLEN]; - /**< Offset in bytes from the beginning of packet's payload - src_offset[i] indicates the flexbyte i's offset in original - packet payload. This value should be less than - flex_payload_limit in struct rte_eth_fdir_info.*/ -}; - -/** - * A structure used to define FDIR masks for flexible payload - * for each flow type - */ -struct rte_eth_fdir_flex_mask { - uint16_t flow_type; - uint8_t mask[RTE_ETH_FDIR_MAX_FLEXLEN]; - /**< Mask for the whole flexible payload */ -}; - - -/* - * A packet can be identified by hardware as different flow types. Different - * NIC hardwares may support different flow types. - * Basically, the NIC hardware identifies the flow type as deep protocol as - * possible, and exclusively. For example, if a packet is identified as - * 'RTE_ETH_FLOW_NONFRAG_IPV4_TCP', it will not be any of other flow types, - * though it is an actual IPV4 packet. - * Note that the flow types are used to define RSS offload types in - * rte_ethdev.h. - */ -#define RTE_ETH_FLOW_UNKNOWN 0 -#define RTE_ETH_FLOW_RAW 1 -#define RTE_ETH_FLOW_IPV4 2 -#define RTE_ETH_FLOW_FRAG_IPV4 3 -#define RTE_ETH_FLOW_NONFRAG_IPV4_TCP 4 -#define RTE_ETH_FLOW_NONFRAG_IPV4_UDP 5 -#define RTE_ETH_FLOW_NONFRAG_IPV4_SCTP 6 -#define RTE_ETH_FLOW_NONFRAG_IPV4_OTHER 7 -#define RTE_ETH_FLOW_IPV6 8 -#define RTE_ETH_FLOW_FRAG_IPV6 9 -#define RTE_ETH_FLOW_NONFRAG_IPV6_TCP 10 -#define RTE_ETH_FLOW_NONFRAG_IPV6_UDP 11 -#define RTE_ETH_FLOW_NONFRAG_IPV6_SCTP 12 -#define RTE_ETH_FLOW_NONFRAG_IPV6_OTHER 13 -#define RTE_ETH_FLOW_L2_PAYLOAD 14 -#define RTE_ETH_FLOW_IPV6_EX 15 -#define RTE_ETH_FLOW_IPV6_TCP_EX 16 -#define RTE_ETH_FLOW_IPV6_UDP_EX 17 -#define RTE_ETH_FLOW_PORT 18 - /**< Consider device port number as a flow differentiator */ -#define RTE_ETH_FLOW_VXLAN 19 /**< VXLAN protocol based flow */ -#define RTE_ETH_FLOW_GENEVE 20 /**< GENEVE protocol based flow */ -#define RTE_ETH_FLOW_NVGRE 21 /**< NVGRE protocol based flow */ -#define RTE_ETH_FLOW_MAX 22 - -/** - * A structure used to define all flexible payload related setting - * include flex payload and flex mask - */ -struct rte_eth_fdir_flex_conf { - uint16_t nb_payloads; /**< The number of following payload cfg */ - uint16_t nb_flexmasks; /**< The number of following mask */ - struct rte_eth_flex_payload_cfg flex_set[RTE_ETH_PAYLOAD_MAX]; - /**< Flex payload configuration for each payload type */ - struct rte_eth_fdir_flex_mask flex_mask[RTE_ETH_FLOW_MAX]; - /**< Flex mask configuration for each flow type */ -}; - -/** - * A structure used to configure the Flow Director (FDIR) feature - * of an Ethernet port. - * - * If mode is RTE_FDIR_DISABLE, the pballoc value is ignored. - */ -struct rte_fdir_conf { - enum rte_fdir_mode mode; /**< Flow Director mode. */ - enum rte_fdir_pballoc_type pballoc; /**< Space for FDIR filters. */ - enum rte_fdir_status_mode status; /**< How to report FDIR hash. */ - /** RX queue of packets matching a "drop" filter in perfect mode. */ - uint8_t drop_queue; - struct rte_eth_fdir_masks mask; - struct rte_eth_fdir_flex_conf flex_conf; - /**< Flex payload configuration. */ -}; - -/** - * A structure used to enable/disable specific device interrupts. - */ -struct rte_intr_conf { - /** enable/disable lsc interrupt. 0 (default) - disable, 1 enable */ - uint16_t lsc; - /** enable/disable rxq interrupt. 0 (default) - disable, 1 enable */ - uint16_t rxq; -}; - -/** - * A structure used to configure an Ethernet port. - * Depending upon the RX multi-queue mode, extra advanced - * configuration settings may be needed. - */ -struct rte_eth_conf { - uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be - used. ETH_LINK_SPEED_FIXED disables link - autonegotiation, and a unique speed shall be - set. Otherwise, the bitmap defines the set of - speeds to be advertised. If the special value - ETH_LINK_SPEED_AUTONEG (0) is used, all speeds - supported are advertised. */ - struct rte_eth_rxmode rxmode; /**< Port RX configuration. */ - struct rte_eth_txmode txmode; /**< Port TX configuration. */ - uint32_t lpbk_mode; /**< Loopback operation mode. By default the value - is 0, meaning the loopback mode is disabled. - Read the datasheet of given ethernet controller - for details. The possible values of this field - are defined in implementation of each driver. */ - struct { - struct rte_eth_rss_conf rss_conf; /**< Port RSS configuration */ - struct rte_eth_vmdq_dcb_conf vmdq_dcb_conf; - /**< Port vmdq+dcb configuration. */ - struct rte_eth_dcb_rx_conf dcb_rx_conf; - /**< Port dcb RX configuration. */ - struct rte_eth_vmdq_rx_conf vmdq_rx_conf; - /**< Port vmdq RX configuration. */ - } rx_adv_conf; /**< Port RX filtering configuration (union). */ - union { - struct rte_eth_vmdq_dcb_tx_conf vmdq_dcb_tx_conf; - /**< Port vmdq+dcb TX configuration. */ - struct rte_eth_dcb_tx_conf dcb_tx_conf; - /**< Port dcb TX configuration. */ - struct rte_eth_vmdq_tx_conf vmdq_tx_conf; - /**< Port vmdq TX configuration. */ - } tx_adv_conf; /**< Port TX DCB configuration (union). */ - /** Currently,Priority Flow Control(PFC) are supported,if DCB with PFC - is needed,and the variable must be set ETH_DCB_PFC_SUPPORT. */ - uint32_t dcb_capability_en; - struct rte_fdir_conf fdir_conf; /**< FDIR configuration. */ - struct rte_intr_conf intr_conf; /**< Interrupt mode configuration. */ -}; diff --git a/bindgen-tests/tests/headers/layout_kni_mbuf.h b/bindgen-tests/tests/headers/layout_kni_mbuf.h index 4d604aa6a8..148cb7df95 100644 --- a/bindgen-tests/tests/headers/layout_kni_mbuf.h +++ b/bindgen-tests/tests/headers/layout_kni_mbuf.h @@ -1,5 +1,3 @@ -// bindgen-flags: --rust-target 1.40 - #define RTE_CACHE_LINE_MIN_SIZE 64 /**< Minimum Cache line size. */ #define RTE_CACHE_LINE_SIZE 64 diff --git a/bindgen-tests/tests/headers/layout_large_align_field.h b/bindgen-tests/tests/headers/layout_large_align_field.h index 63aea90bd9..f292bb70dc 100644 --- a/bindgen-tests/tests/headers/layout_large_align_field.h +++ b/bindgen-tests/tests/headers/layout_large_align_field.h @@ -1,4 +1,4 @@ -// bindgen-flags: --rustified-enum ".*" --rust-target 1.40 +// bindgen-flags: --rustified-enum ".*" typedef unsigned char uint8_t; typedef unsigned short uint16_t; diff --git a/bindgen-tests/tests/headers/layout_mbuf_1_0.h b/bindgen-tests/tests/headers/layout_mbuf_1_0.h deleted file mode 100644 index 2854de5038..0000000000 --- a/bindgen-tests/tests/headers/layout_mbuf_1_0.h +++ /dev/null @@ -1,189 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - - -#define RTE_CACHE_LINE_MIN_SIZE 64 /**< Minimum Cache line size. */ - -#define RTE_CACHE_LINE_SIZE 64 - -typedef char int8_t; -typedef short int16_t; -typedef int int32_t; -typedef long long int64_t; - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; - -typedef uint64_t phys_addr_t; - -/** - * Force alignment - */ -#define __rte_aligned(a) __attribute__((__aligned__(a))) - -/** - * Force alignment to cache line. - */ -#define __rte_cache_aligned __rte_aligned(RTE_CACHE_LINE_SIZE) - -/** - * Force minimum cache line alignment. - */ -#define __rte_cache_min_aligned __rte_aligned(RTE_CACHE_LINE_MIN_SIZE) - -/* define a set of marker types that can be used to refer to set points in the - * mbuf */ -__extension__ -typedef void *MARKER[0]; /**< generic marker for a point in a structure */ -__extension__ -typedef uint8_t MARKER8[0]; /**< generic marker with 1B alignment */ -__extension__ -typedef uint64_t MARKER64[0]; /**< marker that allows us to overwrite 8 bytes - * with a single assignment */ - -/** C extension macro for environments lacking C11 features. */ -#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L -#define RTE_STD_C11 __extension__ -#else -#define RTE_STD_C11 -#endif - -/** - * The atomic counter structure. - */ -typedef struct { - volatile int16_t cnt; /**< An internal counter value. */ -} rte_atomic16_t; - -/** - * The generic rte_mbuf, containing a packet mbuf. - */ -struct rte_mbuf { - MARKER cacheline0; - - void *buf_addr; /**< Virtual address of segment buffer. */ - phys_addr_t buf_physaddr; /**< Physical address of segment buffer. */ - - uint16_t buf_len; /**< Length of segment buffer. */ - - /* next 6 bytes are initialised on RX descriptor rearm */ - MARKER8 rearm_data; - uint16_t data_off; - - /** - * 16-bit Reference counter. - * It should only be accessed using the following functions: - * rte_mbuf_refcnt_update(), rte_mbuf_refcnt_read(), and - * rte_mbuf_refcnt_set(). The functionality of these functions (atomic, - * or non-atomic) is controlled by the CONFIG_RTE_MBUF_REFCNT_ATOMIC - * config option. - */ - RTE_STD_C11 - union { - rte_atomic16_t refcnt_atomic; /**< Atomically accessed refcnt */ - uint16_t refcnt; /**< Non-atomically accessed refcnt */ - }; - uint8_t nb_segs; /**< Number of segments. */ - uint8_t port; /**< Input port. */ - - uint64_t ol_flags; /**< Offload features. */ - - /* remaining bytes are set on RX when pulling packet from descriptor */ - MARKER rx_descriptor_fields1; - - /* - * The packet type, which is the combination of outer/inner L2, L3, L4 - * and tunnel types. The packet_type is about data really present in the - * mbuf. Example: if vlan stripping is enabled, a received vlan packet - * would have RTE_PTYPE_L2_ETHER and not RTE_PTYPE_L2_VLAN because the - * vlan is stripped from the data. - */ - RTE_STD_C11 - union { - uint32_t packet_type; /**< L2/L3/L4 and tunnel information. */ - struct { - uint32_t l2_type:4; /**< (Outer) L2 type. */ - uint32_t l3_type:4; /**< (Outer) L3 type. */ - uint32_t l4_type:4; /**< (Outer) L4 type. */ - uint32_t tun_type:4; /**< Tunnel type. */ - uint32_t inner_l2_type:4; /**< Inner L2 type. */ - uint32_t inner_l3_type:4; /**< Inner L3 type. */ - uint32_t inner_l4_type:4; /**< Inner L4 type. */ - }; - }; - - uint32_t pkt_len; /**< Total pkt len: sum of all segments. */ - uint16_t data_len; /**< Amount of data in segment buffer. */ - /** VLAN TCI (CPU order), valid if PKT_RX_VLAN_STRIPPED is set. */ - uint16_t vlan_tci; - - union { - uint32_t rss; /**< RSS hash result if RSS enabled */ - struct { - RTE_STD_C11 - union { - struct { - uint16_t hash; - uint16_t id; - }; - uint32_t lo; - /**< Second 4 flexible bytes */ - }; - uint32_t hi; - /**< First 4 flexible bytes or FD ID, dependent on - PKT_RX_FDIR_* flag in ol_flags. */ - } fdir; /**< Filter identifier if FDIR enabled */ - struct { - uint32_t lo; - uint32_t hi; - } sched; /**< Hierarchical scheduler */ - uint32_t usr; /**< User defined tags. See rte_distributor_process() */ - } hash; /**< hash information */ - - uint32_t seqn; /**< Sequence number. See also rte_reorder_insert() */ - - /** Outer VLAN TCI (CPU order), valid if PKT_RX_QINQ_STRIPPED is set. */ - uint16_t vlan_tci_outer; - - /* second cache line - fields only used in slow path or on TX */ - MARKER cacheline1 __rte_cache_min_aligned; - - RTE_STD_C11 - union { - void *userdata; /**< Can be used for external metadata */ - uint64_t udata64; /**< Allow 8-byte userdata on 32-bit */ - }; - - struct rte_mempool *pool; /**< Pool from which mbuf was allocated. */ - struct rte_mbuf *next; /**< Next segment of scattered packet. */ - - /* fields to support TX offloads */ - RTE_STD_C11 - union { - uint64_t tx_offload; /**< combined for easy fetch */ - __extension__ - struct { - uint64_t l2_len:7; - /**< L2 (MAC) Header Length for non-tunneling pkt. - * Outer_L4_len + ... + Inner_L2_len for tunneling pkt. - */ - uint64_t l3_len:9; /**< L3 (IP) Header Length. */ - uint64_t l4_len:8; /**< L4 (TCP/UDP) Header Length. */ - uint64_t tso_segsz:16; /**< TCP TSO segment size */ - - /* fields for TX offloading of tunnels */ - uint64_t outer_l3_len:9; /**< Outer L3 (IP) Hdr Length. */ - uint64_t outer_l2_len:7; /**< Outer L2 (MAC) Hdr Length. */ - - /* uint64_t unused:8; */ - }; - }; - - /** Size of the application private data. In case of an indirect - * mbuf, it stores the direct mbuf private data size. */ - uint16_t priv_size; - - /** Timesync flags for use with IEEE1588. */ - uint16_t timesync; -} __rte_cache_aligned; diff --git a/bindgen-tests/tests/headers/long_double.h b/bindgen-tests/tests/headers/long_double.h index 91c4ed6ce9..341be37164 100644 --- a/bindgen-tests/tests/headers/long_double.h +++ b/bindgen-tests/tests/headers/long_double.h @@ -1,5 +1,3 @@ -// bindgen-flags: --rust-target 1.26 - struct foo { long double bar; }; diff --git a/bindgen-tests/tests/headers/macro_const_1_0.h b/bindgen-tests/tests/headers/macro_const_1_0.h deleted file mode 100644 index 3be86b4fd2..0000000000 --- a/bindgen-tests/tests/headers/macro_const_1_0.h +++ /dev/null @@ -1,10 +0,0 @@ -// bindgen-flags: --rust-target 1.0 - -#define foo "bar" -#define CHAR 'b' -#define CHARR '\0' -#define FLOAT 5.09f -#define FLOAT_EXPR (5 / 1000.0f) -#define LONG 3L - -#define INVALID_UTF8 "\xf0\x28\x8c\x28" diff --git a/bindgen-tests/tests/headers/mangling-win32.hpp b/bindgen-tests/tests/headers/mangling-win32.hpp index 386df4aba3..76a7e664ed 100644 --- a/bindgen-tests/tests/headers/mangling-win32.hpp +++ b/bindgen-tests/tests/headers/mangling-win32.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: -- --target=i686-pc-win32 +// bindgen-flags: --raw-line '#![cfg(target = "i686-pc-windows-msvc")]' -- --target=i686-pc-win32 extern "C" void foo(); diff --git a/bindgen-tests/tests/headers/merge-extern-blocks.hpp b/bindgen-tests/tests/headers/merge_extern_blocks_post_1_82.hpp similarity index 81% rename from bindgen-tests/tests/headers/merge-extern-blocks.hpp rename to bindgen-tests/tests/headers/merge_extern_blocks_post_1_82.hpp index 392e34a390..080979f17b 100644 --- a/bindgen-tests/tests/headers/merge-extern-blocks.hpp +++ b/bindgen-tests/tests/headers/merge_extern_blocks_post_1_82.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --merge-extern-blocks --enable-cxx-namespaces -- --target=x86_64-unknown-linux +// bindgen-flags: --merge-extern-blocks --enable-cxx-namespaces --rust-target=1.82 -- --target=x86_64-unknown-linux int foo(); typedef struct Point { int x; diff --git a/bindgen-tests/tests/headers/merge_extern_blocks_pre_1_82.hpp b/bindgen-tests/tests/headers/merge_extern_blocks_pre_1_82.hpp new file mode 100644 index 0000000000..779abf174b --- /dev/null +++ b/bindgen-tests/tests/headers/merge_extern_blocks_pre_1_82.hpp @@ -0,0 +1,14 @@ +// bindgen-flags: --merge-extern-blocks --enable-cxx-namespaces --rust-target=1.81 -- --target=x86_64-unknown-linux +int foo(); +typedef struct Point { + int x; +} Point; +int bar(); + +namespace ns { + int foo(); + typedef struct Point { + int x; + } Point; + int bar(); +} diff --git a/bindgen-tests/tests/headers/namespace/nsdefine.h b/bindgen-tests/tests/headers/namespace/nsdefine.h new file mode 100644 index 0000000000..6504fa9f0a --- /dev/null +++ b/bindgen-tests/tests/headers/namespace/nsdefine.h @@ -0,0 +1,4 @@ +#pragma once + +#define BEGIN_NAMESPACE namespace repro { inline namespace __1 { +#define END_NAMESPACE } } diff --git a/bindgen-tests/tests/headers/nested-class-field.hpp b/bindgen-tests/tests/headers/nested-class-field.hpp new file mode 100644 index 0000000000..295ebe8129 --- /dev/null +++ b/bindgen-tests/tests/headers/nested-class-field.hpp @@ -0,0 +1,7 @@ +class A { + class I; +}; + +class A::I { + int i; +}; diff --git a/bindgen-tests/tests/headers/new-type-alias.h b/bindgen-tests/tests/headers/new-type-alias.h new file mode 100644 index 0000000000..73de94884c --- /dev/null +++ b/bindgen-tests/tests/headers/new-type-alias.h @@ -0,0 +1,22 @@ +// bindgen-flags: --new-type-alias (Foo|Bar|Baz|Bang) + +// Fake stdint.h and stdbool.h +typedef __UINT64_TYPE__ uint64_t; +#define bool _Bool +#define true 1 + +typedef uint64_t Foo; +static const Foo Foo_A = 1; + +typedef char Bar; +static const Bar Bar_A = 'a'; + +typedef float Baz; +static const Baz Baz_A = 3.25; + +typedef bool Bang; +static const Bang Bang_A = true; + +// Not wrapped +typedef uint64_t Boom; +static const Boom Boom_A = 2; diff --git a/bindgen-tests/tests/headers/newtype-enum.hpp b/bindgen-tests/tests/headers/newtype-enum.hpp index 890683ae85..e711ed85bc 100644 --- a/bindgen-tests/tests/headers/newtype-enum.hpp +++ b/bindgen-tests/tests/headers/newtype-enum.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --newtype-enum "Foo" --rust-target 1.28 -- -std=c++11 +// bindgen-flags: --newtype-enum "Foo" -- -std=c++11 enum Foo { Bar = 1 << 1, diff --git a/bindgen-tests/tests/headers/newtype-global-enum.hpp b/bindgen-tests/tests/headers/newtype-global-enum.hpp index 8021a3cc72..c10825fdcf 100644 --- a/bindgen-tests/tests/headers/newtype-global-enum.hpp +++ b/bindgen-tests/tests/headers/newtype-global-enum.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --newtype-global-enum "Foo" --rust-target 1.28 -- -std=c++11 +// bindgen-flags: --newtype-global-enum "Foo" -- -std=c++11 enum Foo { Bar = 1 << 1, diff --git a/bindgen-tests/tests/headers/no_debug_bypass_impl_debug.hpp b/bindgen-tests/tests/headers/no_debug_bypass_impl_debug.hpp index d934d2c7cb..a586441088 100644 --- a/bindgen-tests/tests/headers/no_debug_bypass_impl_debug.hpp +++ b/bindgen-tests/tests/headers/no_debug_bypass_impl_debug.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --no-debug "NoDebug" --impl-debug --rust-target 1.40 +// bindgen-flags: --no-debug "NoDebug" --impl-debug template class Generic { diff --git a/bindgen-tests/tests/headers/no_default_bypass_derive_default.hpp b/bindgen-tests/tests/headers/no_default_bypass_derive_default.hpp index ab0fdfae9f..0f8339062f 100644 --- a/bindgen-tests/tests/headers/no_default_bypass_derive_default.hpp +++ b/bindgen-tests/tests/headers/no_default_bypass_derive_default.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --no-default "NoDefault" --rust-target 1.40 +// bindgen-flags: --no-default "NoDefault" template class Generic { diff --git a/bindgen-tests/tests/headers/opaque-template-inst-member.hpp b/bindgen-tests/tests/headers/opaque-template-inst-member.hpp index 9b327919c1..6516aa564d 100644 --- a/bindgen-tests/tests/headers/opaque-template-inst-member.hpp +++ b/bindgen-tests/tests/headers/opaque-template-inst-member.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --opaque-type 'OpaqueTemplate' --with-derive-hash --with-derive-partialeq --impl-partialeq --with-derive-eq --rust-target 1.40 +// bindgen-flags: --opaque-type 'OpaqueTemplate' --with-derive-hash --with-derive-partialeq --impl-partialeq --with-derive-eq template class OpaqueTemplate { diff --git a/bindgen-tests/tests/headers/opencl_vector.h b/bindgen-tests/tests/headers/opencl_vector.h new file mode 100644 index 0000000000..79022c768f --- /dev/null +++ b/bindgen-tests/tests/headers/opencl_vector.h @@ -0,0 +1,9 @@ +typedef float float4 __attribute__((ext_vector_type(4))); +typedef float float2 __attribute__((ext_vector_type(2))); + +float4 foo(float2 a, float2 b) { + float4 c; + c.xz = a; + c.yw = b; + return c; +} \ No newline at end of file diff --git a/bindgen-tests/tests/headers/operator_equals.hpp b/bindgen-tests/tests/headers/operator_equals.hpp new file mode 100644 index 0000000000..38a3a092a9 --- /dev/null +++ b/bindgen-tests/tests/headers/operator_equals.hpp @@ -0,0 +1,9 @@ +// bindgen-flags: --represent-cxx-operators --generate-inline-functions -- -x c++ +// bindgen-parse-callbacks: operator-rename + +class SomeClass { +public: + bool operator=(const SomeClass& another) { + return false; + } +}; diff --git a/bindgen-tests/tests/headers/packed-vtable.h b/bindgen-tests/tests/headers/packed-vtable.h index d2413d4571..b3405977b5 100644 --- a/bindgen-tests/tests/headers/packed-vtable.h +++ b/bindgen-tests/tests/headers/packed-vtable.h @@ -1,4 +1,4 @@ -// bindgen-flags: --raw-line '#![cfg(feature = "nightly")]' --rust-target 1.33 -- -x c++ -std=c++11 +// bindgen-flags: --raw-line '#![cfg(feature = "nightly")]' -- -x c++ -std=c++11 #pragma pack(1) diff --git a/bindgen-tests/tests/headers/references.hpp b/bindgen-tests/tests/headers/references.hpp new file mode 100644 index 0000000000..6b56823d12 --- /dev/null +++ b/bindgen-tests/tests/headers/references.hpp @@ -0,0 +1,17 @@ +// bindgen-flags: --nonnull-references + +struct Container { + int *normalPointer; + const int *constPointer; + int &normalRef; + const int &constRef; + int *&pointerRef; + const int *&constPointerRef; +}; + +int &refReturningFunction(); + +void functionConsumingRef(int &someRef, float normalArgument, + const int &constRef); + +void functionConsumingPointerRef(int* &pointerRef); diff --git a/bindgen-tests/tests/headers/repr-align.hpp b/bindgen-tests/tests/headers/repr-align.hpp index 3347594b5c..a7719e10ed 100644 --- a/bindgen-tests/tests/headers/repr-align.hpp +++ b/bindgen-tests/tests/headers/repr-align.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --raw-line '#![cfg(feature = "nightly")]' --rust-target 1.25 -- -std=c++11 +// bindgen-flags: --raw-line '#![cfg(feature = "nightly")]' -- -std=c++11 struct alignas(8) a { int b; diff --git a/bindgen-tests/tests/headers/special-members.hpp b/bindgen-tests/tests/headers/special-members.hpp new file mode 100644 index 0000000000..753b2fdc0a --- /dev/null +++ b/bindgen-tests/tests/headers/special-members.hpp @@ -0,0 +1,7 @@ +class A { +public: + A(); + A(A&); + A(A&&); + ~A(); +}; \ No newline at end of file diff --git a/bindgen-tests/tests/headers/specific_receiver.hpp b/bindgen-tests/tests/headers/specific_receiver.hpp new file mode 100644 index 0000000000..a521f9f0b2 --- /dev/null +++ b/bindgen-tests/tests/headers/specific_receiver.hpp @@ -0,0 +1,7 @@ +// bindgen-flags: --use-specific-virtual-function-receiver --generate-inline-functions -- -x c++ -std=c++14 + +class Fish { +public: + virtual void swim() { + } +}; diff --git a/bindgen-tests/tests/headers/strings_array.h b/bindgen-tests/tests/headers/strings_array.h index 6a61d71049..fa7bf561fa 100644 --- a/bindgen-tests/tests/headers/strings_array.h +++ b/bindgen-tests/tests/headers/strings_array.h @@ -1,5 +1,3 @@ -// bindgen-flags: --rust-target=1.0 - const char* MY_STRING_UTF8 = "Hello, world!"; const char* MY_STRING_INTERIOR_NULL = "Hello,\0World!"; const char* MY_STRING_NON_UTF8 = "ABCDE\xFF"; diff --git a/bindgen-tests/tests/headers/strings_cstr2.h b/bindgen-tests/tests/headers/strings_cstr2.h new file mode 100644 index 0000000000..2cd7e6222d --- /dev/null +++ b/bindgen-tests/tests/headers/strings_cstr2.h @@ -0,0 +1,5 @@ +// bindgen-flags: --rust-target=1.77 --generate-cstr + +const char* MY_STRING_UTF8 = "Hello, world!"; +const char* MY_STRING_INTERIOR_NULL = "Hello,\0World!"; +const char* MY_STRING_NON_UTF8 = "ABCDE\xFF"; diff --git a/bindgen-tests/tests/headers/strings_cstr2_2018.h b/bindgen-tests/tests/headers/strings_cstr2_2018.h new file mode 100644 index 0000000000..67d117a1bc --- /dev/null +++ b/bindgen-tests/tests/headers/strings_cstr2_2018.h @@ -0,0 +1,5 @@ +// bindgen-flags: --rust-target=1.77 --rust-edition=2018 --generate-cstr + +const char* MY_STRING_UTF8 = "Hello, world!"; +const char* MY_STRING_INTERIOR_NULL = "Hello,\0World!"; +const char* MY_STRING_NON_UTF8 = "ABCDE\xFF"; diff --git a/bindgen-tests/tests/headers/struct_with_anon_union_1_0.h b/bindgen-tests/tests/headers/struct_with_anon_union_1_0.h deleted file mode 100644 index 847c354b59..0000000000 --- a/bindgen-tests/tests/headers/struct_with_anon_union_1_0.h +++ /dev/null @@ -1,8 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -struct foo { - union { - unsigned int a; - unsigned short b; - } bar; -}; diff --git a/bindgen-tests/tests/headers/struct_with_anon_unnamed_union_1_0.h b/bindgen-tests/tests/headers/struct_with_anon_unnamed_union_1_0.h deleted file mode 100644 index 791a1593af..0000000000 --- a/bindgen-tests/tests/headers/struct_with_anon_unnamed_union_1_0.h +++ /dev/null @@ -1,8 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -struct foo { - union { - unsigned int a; - unsigned short b; - }; -}; diff --git a/bindgen-tests/tests/headers/struct_with_derive_debug.h b/bindgen-tests/tests/headers/struct_with_derive_debug.h index 4dc816b787..201748d9c5 100644 --- a/bindgen-tests/tests/headers/struct_with_derive_debug.h +++ b/bindgen-tests/tests/headers/struct_with_derive_debug.h @@ -1,4 +1,4 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --rust-target 1.40 +// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq // struct LittleArray { int a[32]; diff --git a/bindgen-tests/tests/headers/struct_with_large_array.hpp b/bindgen-tests/tests/headers/struct_with_large_array.hpp index 974ca526a3..58e8e4d19a 100644 --- a/bindgen-tests/tests/headers/struct_with_large_array.hpp +++ b/bindgen-tests/tests/headers/struct_with_large_array.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --rust-target 1.40 +// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq // struct S { char large_array[33]; diff --git a/bindgen-tests/tests/headers/struct_with_nesting_1_0.h b/bindgen-tests/tests/headers/struct_with_nesting_1_0.h deleted file mode 100644 index a24ae1db58..0000000000 --- a/bindgen-tests/tests/headers/struct_with_nesting_1_0.h +++ /dev/null @@ -1,19 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -struct foo { - unsigned int a; - union { - unsigned int b; - struct { - unsigned short c1; - unsigned short c2; - }; - - struct { - unsigned char d1; - unsigned char d2; - unsigned char d3; - unsigned char d4; - }; - }; -}; diff --git a/bindgen-tests/tests/headers/transform-op.hpp b/bindgen-tests/tests/headers/transform-op.hpp index aa6118eb67..090e88b34b 100644 --- a/bindgen-tests/tests/headers/transform-op.hpp +++ b/bindgen-tests/tests/headers/transform-op.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --rust-target 1.0 -- -std=c++11 +// bindgen-flags: -- -std=c++11 typedef unsigned char uint8_t; typedef int int32_t; diff --git a/bindgen-tests/tests/headers/typeref_1_0.hpp b/bindgen-tests/tests/headers/typeref_1_0.hpp deleted file mode 100644 index 70dfc11fb1..0000000000 --- a/bindgen-tests/tests/headers/typeref_1_0.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -struct nsFoo; - -namespace mozilla { - -struct FragmentOrURL { bool mIsLocalRef; }; -struct Position { }; - -} // namespace mozilla - -class Bar { - nsFoo* mFoo; -}; - -namespace mozilla { - -template -struct StyleShapeSource { - union { - Position* mPosition; - FragmentOrURL* mFragmentOrURL; - }; -}; - -} // namespace mozilla - -struct nsFoo { - mozilla::StyleShapeSource mBar; -}; diff --git a/bindgen-tests/tests/headers/uncallable_functions.hpp b/bindgen-tests/tests/headers/uncallable_functions.hpp new file mode 100644 index 0000000000..9187470c65 --- /dev/null +++ b/bindgen-tests/tests/headers/uncallable_functions.hpp @@ -0,0 +1,9 @@ +// bindgen-flags: --generate-deleted-functions --generate-private-functions --generate-pure-virtual-functions --generate-inline-functions -- -x c++ -std=c++14 + +class Test { +public: + virtual void a() = 0; + void b() = delete; +private: + void c() {} +}; diff --git a/bindgen-tests/tests/headers/union-align.h b/bindgen-tests/tests/headers/union-align.h index 9557b2798a..5ed955f25e 100644 --- a/bindgen-tests/tests/headers/union-align.h +++ b/bindgen-tests/tests/headers/union-align.h @@ -1,5 +1,3 @@ -// bindgen-flags: --rust-target 1.26 - union Bar { unsigned char foo; } __attribute__ ((__aligned__ (16))); diff --git a/bindgen-tests/tests/headers/union-in-ns_1_0.hpp b/bindgen-tests/tests/headers/union-in-ns_1_0.hpp deleted file mode 100644 index f3ae221057..0000000000 --- a/bindgen-tests/tests/headers/union-in-ns_1_0.hpp +++ /dev/null @@ -1,5 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --enable-cxx-namespaces - -union bar { - int baz; -}; diff --git a/bindgen-tests/tests/headers/union_bitfield.h b/bindgen-tests/tests/headers/union_bitfield.h index 990729574a..4592a8973a 100644 --- a/bindgen-tests/tests/headers/union_bitfield.h +++ b/bindgen-tests/tests/headers/union_bitfield.h @@ -1,10 +1,10 @@ // bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq union U4 { - unsigned derp : 1; + unsigned int derp:1; /* 0: 0 4 */ }; union B { - unsigned foo : 31; - unsigned char bar : 1; + unsigned int foo:31; /* 0: 0 4 */ + unsigned char bar:1; /* 0: 0 1 */ }; diff --git a/bindgen-tests/tests/headers/union_bitfield_1_0.h b/bindgen-tests/tests/headers/union_bitfield_1_0.h deleted file mode 100644 index 06b61ad771..0000000000 --- a/bindgen-tests/tests/headers/union_bitfield_1_0.h +++ /dev/null @@ -1,14 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq - -union U4 { - unsigned derp : 1; -}; - -union B { - unsigned foo : 31; - unsigned char bar : 1; -}; - -union HasBigBitfield { - __int128 x : 128; -}; diff --git a/bindgen-tests/tests/headers/union_dtor_1_0.hpp b/bindgen-tests/tests/headers/union_dtor_1_0.hpp deleted file mode 100644 index 01f7636671..0000000000 --- a/bindgen-tests/tests/headers/union_dtor_1_0.hpp +++ /dev/null @@ -1,7 +0,0 @@ -// bindgen-flags: --rust-target 1.0 - -union UnionWithDtor { - ~UnionWithDtor(); - int mFoo; - void* mBar; -}; diff --git a/bindgen-tests/tests/headers/union_fields_1_0.hpp b/bindgen-tests/tests/headers/union_fields_1_0.hpp deleted file mode 100644 index bbb67fbc6e..0000000000 --- a/bindgen-tests/tests/headers/union_fields_1_0.hpp +++ /dev/null @@ -1,7 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -typedef union { - int mInt; - float mFloat; - void* mPointer; -} nsStyleUnion; diff --git a/bindgen-tests/tests/headers/union_template_1_0.hpp b/bindgen-tests/tests/headers/union_template_1_0.hpp deleted file mode 100644 index 18e3d74a37..0000000000 --- a/bindgen-tests/tests/headers/union_template_1_0.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -template -struct NastyStruct { - bool mIsSome; - union { - void* mFoo; - unsigned long mDummy; - } mStorage; - - union { - short wat; - int* wut; - }; -}; - -template -union Whatever { - void* mTPtr; - int mInt; -}; diff --git a/bindgen-tests/tests/headers/union_with_anon_struct_1_0.h b/bindgen-tests/tests/headers/union_with_anon_struct_1_0.h deleted file mode 100644 index 9313299eb0..0000000000 --- a/bindgen-tests/tests/headers/union_with_anon_struct_1_0.h +++ /dev/null @@ -1,8 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -union foo { - struct { - unsigned int a; - unsigned int b; - } bar; -}; diff --git a/bindgen-tests/tests/headers/union_with_anon_struct_bitfield_1_0.h b/bindgen-tests/tests/headers/union_with_anon_struct_bitfield_1_0.h deleted file mode 100644 index 0b0e3d7371..0000000000 --- a/bindgen-tests/tests/headers/union_with_anon_struct_bitfield_1_0.h +++ /dev/null @@ -1,9 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -union foo { - int a; - struct { - int b : 7; - int c : 25; - }; -}; diff --git a/bindgen-tests/tests/headers/union_with_anon_union_1_0.h b/bindgen-tests/tests/headers/union_with_anon_union_1_0.h deleted file mode 100644 index 28a7231dbf..0000000000 --- a/bindgen-tests/tests/headers/union_with_anon_union_1_0.h +++ /dev/null @@ -1,8 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -union foo { - union { - unsigned int a; - unsigned short b; - } bar; -}; diff --git a/bindgen-tests/tests/headers/union_with_anon_unnamed_struct_1_0.h b/bindgen-tests/tests/headers/union_with_anon_unnamed_struct_1_0.h deleted file mode 100644 index 506a41f661..0000000000 --- a/bindgen-tests/tests/headers/union_with_anon_unnamed_struct_1_0.h +++ /dev/null @@ -1,11 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -union pixel { - unsigned int rgba; - struct { - unsigned char r; - unsigned char g; - unsigned char b; - unsigned char a; - }; -}; diff --git a/bindgen-tests/tests/headers/union_with_anon_unnamed_union_1_0.h b/bindgen-tests/tests/headers/union_with_anon_unnamed_union_1_0.h deleted file mode 100644 index c556a61311..0000000000 --- a/bindgen-tests/tests/headers/union_with_anon_unnamed_union_1_0.h +++ /dev/null @@ -1,9 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -union foo { - unsigned int a; - union { - unsigned short b; - unsigned char c; - }; -}; diff --git a/bindgen-tests/tests/headers/union_with_big_member_1_0.h b/bindgen-tests/tests/headers/union_with_big_member_1_0.h deleted file mode 100644 index 0429435478..0000000000 --- a/bindgen-tests/tests/headers/union_with_big_member_1_0.h +++ /dev/null @@ -1,16 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -union WithBigArray { - int a; - int b[33]; -}; - -union WithBigArray2 { - int a; - char b[33]; -}; - -union WithBigMember { - int a; - union WithBigArray b; -}; diff --git a/bindgen-tests/tests/headers/union_with_nesting_1_0.h b/bindgen-tests/tests/headers/union_with_nesting_1_0.h deleted file mode 100644 index 3cdb7238bc..0000000000 --- a/bindgen-tests/tests/headers/union_with_nesting_1_0.h +++ /dev/null @@ -1,16 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq - -union foo { - unsigned int a; - struct { - union { - unsigned short b1; - unsigned short b2; - }; - - union { - unsigned short c1; - unsigned short c2; - }; - }; -}; diff --git a/bindgen-tests/tests/headers/union_with_zero_sized_array.h b/bindgen-tests/tests/headers/union_with_zero_sized_array.h new file mode 100644 index 0000000000..ace745f26c --- /dev/null +++ b/bindgen-tests/tests/headers/union_with_zero_sized_array.h @@ -0,0 +1,5 @@ +union U { + char d0[0]; + char d1[1]; + char d2[2]; +}; diff --git a/bindgen-tests/tests/headers/use-core_1_0.h b/bindgen-tests/tests/headers/use-core_1_0.h deleted file mode 100644 index 40de9d158d..0000000000 --- a/bindgen-tests/tests/headers/use-core_1_0.h +++ /dev/null @@ -1,13 +0,0 @@ -// bindgen-flags: --rust-target 1.0 --use-core --raw-line "extern crate core;" --with-derive-hash --with-derive-partialeq --with-derive-eq - -struct foo { - int a, b; - void* bar; -}; - -union { - int bar; - long baz; -} bazz; - -typedef void (*fooFunction)(int bar); diff --git a/bindgen-tests/tests/headers/va_list_aarch64_linux.h b/bindgen-tests/tests/headers/va_list_aarch64_linux.h new file mode 100644 index 0000000000..7d2206a76e --- /dev/null +++ b/bindgen-tests/tests/headers/va_list_aarch64_linux.h @@ -0,0 +1,4 @@ +// bindgen-flags: -- --target=aarch64-unknown-linux-gnu + +typedef __builtin_va_list va_list; +int vprintf(const char* format, va_list vlist); diff --git a/bindgen-tests/tests/headers/variadic-union.hpp b/bindgen-tests/tests/headers/variadic-union.hpp new file mode 100644 index 0000000000..62ed49fcc9 --- /dev/null +++ b/bindgen-tests/tests/headers/variadic-union.hpp @@ -0,0 +1,3 @@ +template union _Variadic_union { + _Variadic_union() = default; +}; diff --git a/bindgen-tests/tests/headers/win32-dtors.hpp b/bindgen-tests/tests/headers/win32-dtors.hpp index dc9b0fdc6e..0f0f0e1604 100644 --- a/bindgen-tests/tests/headers/win32-dtors.hpp +++ b/bindgen-tests/tests/headers/win32-dtors.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --rust-target 1.0 -- --target=x86_64-pc-windows-msvc +// bindgen-flags: -- --target=x86_64-pc-windows-msvc struct CppObj { int x; @@ -26,4 +26,4 @@ struct CppObj4 : CppObj2 { CppObj4(int x); ~CppObj4(); -}; \ No newline at end of file +}; diff --git a/bindgen-tests/tests/headers/win32-thiscall.hpp b/bindgen-tests/tests/headers/win32-thiscall.hpp new file mode 100644 index 0000000000..4651f809a1 --- /dev/null +++ b/bindgen-tests/tests/headers/win32-thiscall.hpp @@ -0,0 +1,7 @@ +// bindgen-flags: --raw-line "#![cfg(not(test))]" -- --target=i686-pc-windows-msvc + +class Foo { + public: + void test(); + int test2(int var); +}; diff --git a/bindgen-tests/tests/headers/win32-thiscall_1_0.hpp b/bindgen-tests/tests/headers/win32-thiscall_1_0.hpp deleted file mode 100644 index 5907c76eaf..0000000000 --- a/bindgen-tests/tests/headers/win32-thiscall_1_0.hpp +++ /dev/null @@ -1,7 +0,0 @@ -// bindgen-flags: --rust-target 1.0 -- --target=i686-pc-windows-msvc - -class Foo { - public: - void test(); - int test2(int var); -}; diff --git a/bindgen-tests/tests/headers/win32-vectorcall-1_0.h b/bindgen-tests/tests/headers/win32-vectorcall-1_0.h deleted file mode 100644 index a1f852b52f..0000000000 --- a/bindgen-tests/tests/headers/win32-vectorcall-1_0.h +++ /dev/null @@ -1,3 +0,0 @@ -// bindgen-flags: --rust-target 1.0 -- --target=x86_64-pc-windows-msvc - -int __vectorcall test_vectorcall(int a, int b); diff --git a/bindgen-tests/tests/headers/win32-vectorcall.h b/bindgen-tests/tests/headers/win32-vectorcall.h new file mode 100644 index 0000000000..3fe36f1004 --- /dev/null +++ b/bindgen-tests/tests/headers/win32-vectorcall.h @@ -0,0 +1,3 @@ +// bindgen-flags: -- --target=x86_64-pc-windows-msvc + +int __vectorcall test_vectorcall(int a, int b); diff --git a/bindgen-tests/tests/headers/wrap-static-fns.h b/bindgen-tests/tests/headers/wrap-static-fns.h index 2be7bd93d9..a35e713f2b 100644 --- a/bindgen-tests/tests/headers/wrap-static-fns.h +++ b/bindgen-tests/tests/headers/wrap-static-fns.h @@ -1,4 +1,4 @@ -// bindgen-flags: --experimental --wrap-static-fns +// bindgen-flags: --wrap-static-fns // bindgen-parse-callbacks: wrap-as-variadic-fn // to avoid polluting the expectation tests we put the stdarg.h behind a conditional @@ -60,6 +60,10 @@ static inline int variadic(int x, ...) { return x; } +// aarch64-linux has a bug, remove ifdef when it is solved: +// https://github.com/rust-lang/rust-bindgen/issues/3234 +#ifndef DISABLE_VA + static inline void no_extra_argument(__builtin_va_list va) {} static inline int many_va_list(int i, __builtin_va_list va1, __builtin_va_list va2) { @@ -84,3 +88,4 @@ static inline int wrap_as_variadic_fn1(int i, va_list va) { static inline void wrap_as_variadic_fn2(int i, va_list va) {} #endif +#endif diff --git a/bindgen-tests/tests/headers/wrap_unsafe_ops_anon_union_1_0.hpp b/bindgen-tests/tests/headers/wrap_unsafe_ops_anon_union.hpp similarity index 83% rename from bindgen-tests/tests/headers/wrap_unsafe_ops_anon_union_1_0.hpp rename to bindgen-tests/tests/headers/wrap_unsafe_ops_anon_union.hpp index 3b595f2ea7..34faea5d90 100644 --- a/bindgen-tests/tests/headers/wrap_unsafe_ops_anon_union_1_0.hpp +++ b/bindgen-tests/tests/headers/wrap_unsafe_ops_anon_union.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: --rust-target 1.0 --wrap-unsafe-ops --no-layout-tests +// bindgen-flags: --wrap-unsafe-ops --no-layout-tests template struct TErrorResult { diff --git a/bindgen-tests/tests/headers/wrap_unsafe_ops_dynamic_loading_simple.h b/bindgen-tests/tests/headers/wrap_unsafe_ops_dynamic_loading_simple.h index 2b8c107185..36a638ae2a 100644 --- a/bindgen-tests/tests/headers/wrap_unsafe_ops_dynamic_loading_simple.h +++ b/bindgen-tests/tests/headers/wrap_unsafe_ops_dynamic_loading_simple.h @@ -3,3 +3,5 @@ int foo(int x, int y); int bar(void *x); int baz(); + +const int FLUX; diff --git a/bindgen-tests/tests/parse_callbacks/add_derives_callback/header_add_derives.h b/bindgen-tests/tests/parse_callbacks/add_derives_callback/header_add_derives.h new file mode 100644 index 0000000000..8cc64a8806 --- /dev/null +++ b/bindgen-tests/tests/parse_callbacks/add_derives_callback/header_add_derives.h @@ -0,0 +1,3 @@ +struct SimpleStruct { + int a; +}; diff --git a/bindgen-tests/tests/parse_callbacks/add_derives_callback/mod.rs b/bindgen-tests/tests/parse_callbacks/add_derives_callback/mod.rs new file mode 100644 index 0000000000..50e9cbd814 --- /dev/null +++ b/bindgen-tests/tests/parse_callbacks/add_derives_callback/mod.rs @@ -0,0 +1,106 @@ +#[cfg(test)] +mod tests { + use bindgen::callbacks::{DeriveInfo, ParseCallbacks}; + use bindgen::{Bindings, Builder}; + use std::path::{Path, PathBuf}; + + #[derive(Debug)] + struct AddDerivesCallback(Vec); + + impl AddDerivesCallback { + fn new(derives: &[&str]) -> Self { + Self(derives.iter().map(|s| (*s).to_string()).collect()) + } + } + + impl ParseCallbacks for AddDerivesCallback { + fn add_derives(&self, _info: &DeriveInfo<'_>) -> Vec { + self.0.clone() + } + } + + struct WriteAdapter<'a>(&'a mut Vec); + + impl std::io::Write for WriteAdapter<'_> { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.0.extend_from_slice(buf); + Ok(buf.len()) + } + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } + } + + fn write_bindings_to_string(bindings: &Bindings) -> String { + let mut output = Vec::::new(); + bindings + .write(Box::new(WriteAdapter(&mut output))) + .unwrap_or_else(|e| { + panic!("Failed to write generated bindings: {e}") + }); + String::from_utf8(output).unwrap_or_else(|e| { + panic!("Failed to convert generated bindings to string: {e}") + }) + } + + fn make_builder(header_path: &Path, add_derives: &[&str]) -> Builder { + Builder::default() + .header(header_path.display().to_string()) + .derive_debug(true) + .derive_copy(false) + .derive_default(false) + .derive_partialeq(false) + .derive_eq(false) + .derive_partialord(false) + .derive_ord(false) + .derive_hash(false) + .parse_callbacks(Box::new(AddDerivesCallback::new(add_derives))) + } + + /// Tests that adding a derive trait that's already derived automatically + /// does not result in a duplicate derive trait (which would not compile). + #[test] + fn test_add_derives_callback_dedupe() { + let crate_dir = + PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); + let header_path = crate_dir.join( + "tests/parse_callbacks/add_derives_callback/header_add_derives.h", + ); + + let builder = make_builder(&header_path, &["Debug"]); + let bindings = builder + .generate() + .unwrap_or_else(|e| panic!("Failed to generate bindings: {e}")); + let output = write_bindings_to_string(&bindings); + let output_without_spaces = output.replace(' ', ""); + assert!( + output_without_spaces.contains("#[derive(Debug)]") && + !output_without_spaces.contains("#[derive(Debug,Debug)]"), + "Unexpected bindgen output:\n{}", + output.as_str() + ); + } + + /// Tests that adding a derive trait that's not already derived automatically + /// adds it to the end of the derive list. + #[test] + fn test_add_derives_callback() { + let crate_dir = + PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); + let header_path = crate_dir.join( + "tests/parse_callbacks/add_derives_callback/header_add_derives.h", + ); + + let builder = make_builder(&header_path, &["Default"]); + let bindings = builder + .generate() + .unwrap_or_else(|e| panic!("Failed to generate bindings: {e}")); + let output = write_bindings_to_string(&bindings); + let output_without_spaces = output.replace(' ', ""); + assert!( + output_without_spaces.contains("#[derive(Debug,Default)]"), + "Unexpected bindgen output:\n{}", + output.as_str() + ); + } +} diff --git a/bindgen-tests/tests/parse_callbacks/item_discovery_callback/header_item_discovery.h b/bindgen-tests/tests/parse_callbacks/item_discovery_callback/header_item_discovery.h new file mode 100644 index 0000000000..fd385556d4 --- /dev/null +++ b/bindgen-tests/tests/parse_callbacks/item_discovery_callback/header_item_discovery.h @@ -0,0 +1,40 @@ +// Structs +void function_using_anonymous_struct(struct {} arg0); + +struct NamedStruct { +}; + +typedef struct NamedStruct AliasOfNamedStruct; + + +// Unions +void function_using_anonymous_union(union {} arg0); + +union NamedUnion { +}; + +typedef union NamedUnion AliasOfNamedUnion; + +// Enums + +// We don't include an anonymous enum because such enums +// are not visible outside the function, and thus tend not +// to be useful - bindgen doesn't handle them for this reason. + +enum NamedEnum { + Fish, +}; + +typedef enum NamedEnum AliasOfNamedEnum; + +// Functions + +void named_function(); + +// Constants + +const int MOD = 998244353; + +// Variable + +const char* name; diff --git a/bindgen-tests/tests/parse_callbacks/item_discovery_callback/header_item_discovery.hpp b/bindgen-tests/tests/parse_callbacks/item_discovery_callback/header_item_discovery.hpp new file mode 100644 index 0000000000..1de8d99e4d --- /dev/null +++ b/bindgen-tests/tests/parse_callbacks/item_discovery_callback/header_item_discovery.hpp @@ -0,0 +1,6 @@ +// Methods + +class SomeClass { +public: + void named_method(); +}; \ No newline at end of file diff --git a/bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs b/bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs new file mode 100644 index 0000000000..5040d100fe --- /dev/null +++ b/bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs @@ -0,0 +1,586 @@ +use std::cell::RefCell; +use std::collections::HashMap; +use std::rc::Rc; + +use regex::Regex; + +use bindgen::callbacks::{ + DiscoveredItem, DiscoveredItemId, ParseCallbacks, SourceLocation, +}; +use bindgen::Builder; + +#[derive(Debug, Default)] +struct ItemDiscovery(Rc>); + +pub type ItemCache = HashMap; + +#[derive(Debug)] +pub struct DiscoveredInformation(DiscoveredItem, Option); + +impl ParseCallbacks for ItemDiscovery { + fn new_item_found( + &self, + id: DiscoveredItemId, + item: DiscoveredItem, + source_location: Option<&SourceLocation>, + ) { + self.0 + .borrow_mut() + .insert(id, DiscoveredInformation(item, source_location.cloned())); + } +} + +#[derive(Debug)] +pub struct ItemExpectations { + item: DiscoveredItem, + source_location: Option<(usize, usize, usize)>, +} + +impl ItemExpectations { + fn new( + item: DiscoveredItem, + line: usize, + col: usize, + byte_offset: usize, + ) -> Self { + Self { + item, + source_location: Some((line, col, byte_offset)), + } + } +} + +type ExpectationMap = HashMap; + +fn test_item_discovery_callback( + header: &str, + expected: &HashMap, +) { + let discovery = ItemDiscovery::default(); + let info = Rc::clone(&discovery.0); + + let mut header_path = env!("CARGO_MANIFEST_DIR").to_string(); + header_path.push_str(header); + + Builder::default() + .header(header_path) + .parse_callbacks(Box::new(discovery)) + .generate() + .expect("TODO: panic message"); + + compare_item_caches(&info.borrow(), expected, header); +} + +#[test] +fn test_item_discovery_callback_c() { + let expected = ExpectationMap::from([ + ( + DiscoveredItemId::new(10), + ItemExpectations::new( + DiscoveredItem::Struct { + original_name: Some("NamedStruct".to_string()), + final_name: "NamedStruct".to_string(), + }, + 4, + 8, + 73, + ), + ), + ( + DiscoveredItemId::new(11), + ItemExpectations::new( + DiscoveredItem::Alias { + alias_name: "AliasOfNamedStruct".to_string(), + alias_for: DiscoveredItemId::new(10), + }, + 7, + 28, + 118, + ), + ), + ( + DiscoveredItemId::new(20), + ItemExpectations::new( + DiscoveredItem::Union { + original_name: Some("NamedUnion".to_string()), + final_name: "NamedUnion".to_string(), + }, + 13, + 7, + 209, + ), + ), + ( + DiscoveredItemId::new(21), + ItemExpectations::new( + DiscoveredItem::Alias { + alias_name: "AliasOfNamedUnion".to_string(), + alias_for: DiscoveredItemId::new(20), + }, + 16, + 26, + 251, + ), + ), + ( + DiscoveredItemId::new(27), + ItemExpectations::new( + DiscoveredItem::Alias { + alias_name: "AliasOfNamedEnum".to_string(), + alias_for: DiscoveredItemId::new(24), + }, + 28, + 24, + 515, + ), + ), + ( + DiscoveredItemId::new(24), + ItemExpectations::new( + DiscoveredItem::Enum { + final_name: "NamedEnum".to_string(), + }, + 24, + 6, + 466, + ), + ), + ( + DiscoveredItemId::new(30), + ItemExpectations::new( + DiscoveredItem::Struct { + original_name: None, + final_name: "_bindgen_ty_*".to_string(), + }, + 2, + 38, + 48, + ), + ), + ( + DiscoveredItemId::new(40), + ItemExpectations::new( + DiscoveredItem::Union { + original_name: None, + final_name: "_bindgen_ty_*".to_string(), + }, + 11, + 37, + 186, + ), + ), + ( + DiscoveredItemId::new(41), + ItemExpectations::new( + DiscoveredItem::Function { + final_name: "named_function".to_string(), + }, + 32, + 6, + 553, + ), + ), + ( + DiscoveredItemId::new(30), + ItemExpectations::new( + DiscoveredItem::Constant { + final_name: "MOD".to_string(), + }, + 36, + 11, + 596, + ), + ), + ( + DiscoveredItemId::new(34), + ItemExpectations::new( + DiscoveredItem::Variable { + final_name: "name".to_string(), + }, + 40, + 13, + 639, + ), + ), + ]); + test_item_discovery_callback( + "/tests/parse_callbacks/item_discovery_callback/header_item_discovery.h", &expected); +} + +#[test] +fn test_item_discovery_callback_cpp() { + let expected = ExpectationMap::from([ + ( + DiscoveredItemId::new(1), + ItemExpectations::new( + DiscoveredItem::Struct { + original_name: Some("SomeClass".to_string()), + final_name: "SomeClass".to_string(), + }, + 3, + 7, + 18, + ), + ), + ( + DiscoveredItemId::new(2), + ItemExpectations::new( + DiscoveredItem::Method { + final_name: "named_method".to_string(), + parent: DiscoveredItemId::new(1), + }, + 5, + 10, + 47, + ), + ), + ]); + test_item_discovery_callback( + "/tests/parse_callbacks/item_discovery_callback/header_item_discovery.hpp", &expected); +} + +fn compare_item_caches( + generated: &ItemCache, + expected: &ExpectationMap, + expected_filename: &str, +) { + // We can't use a simple Eq::eq comparison because of two reasons: + // - anonymous structs/unions will have a final name generated by bindgen which may change + // if the header file or the bindgen logic is altered + // - aliases have a DiscoveredItemId that we can't directly compare for the same instability reasons + for expected_item in expected.values() { + let found = generated.iter().find(|(_generated_id, generated_item)| { + compare_item_info( + expected_item, + generated_item, + expected, + generated, + expected_filename, + ) + }); + + assert!( + found.is_some(), + "Missing Expected Item: {expected_item:#?}\n in {generated:#?}" + ); + } +} + +fn compare_item_info( + expected_item: &ItemExpectations, + generated_item: &DiscoveredInformation, + expected: &ExpectationMap, + generated: &ItemCache, + expected_filename: &str, +) -> bool { + if std::mem::discriminant(&expected_item.item) != + std::mem::discriminant(&generated_item.0) + { + return false; + } + + let is_a_match = match generated_item.0 { + DiscoveredItem::Struct { .. } => { + compare_struct_info(&expected_item.item, &generated_item.0) + } + DiscoveredItem::Union { .. } => { + compare_union_info(&expected_item.item, &generated_item.0) + } + DiscoveredItem::Alias { .. } => compare_alias_info( + &expected_item.item, + &generated_item.0, + expected, + generated, + expected_filename, + ), + DiscoveredItem::Enum { .. } => { + compare_enum_info(&expected_item.item, &generated_item.0) + } + DiscoveredItem::Function { .. } => { + compare_function_info(&expected_item.item, &generated_item.0) + } + DiscoveredItem::Method { .. } => { + compare_method_info(&expected_item.item, &generated_item.0) + } + DiscoveredItem::Constant { .. } => { + compare_constant_info(&expected_item.item, &generated_item.0) + } + DiscoveredItem::Variable { .. } => { + compare_variable_info(&expected_item.item, &generated_item.0) + } + }; + + if is_a_match { + // Compare source location + assert!( + generated_item.1.is_some() == + expected_item.source_location.is_some(), + "No source location provided when one was expected" + ); + if let Some(generated_location) = generated_item.1.as_ref() { + let expected_location = expected_item.source_location.unwrap(); + assert!( + generated_location + .file_name + .as_ref() + .expect("No filename provided") + .ends_with(expected_filename), + "Filename differed" + ); + assert_eq!( + ( + generated_location.line, + generated_location.col, + generated_location.byte_offset + ), + expected_location, + "Line/col/offsets differ" + ); + } + } + is_a_match +} + +pub fn compare_names(expected_name: &str, generated_name: &str) -> bool { + if let Ok(regex) = Regex::new(expected_name) { + regex.is_match(generated_name) + } else { + false + } +} + +pub fn compare_struct_info( + expected_item: &DiscoveredItem, + generated_item: &DiscoveredItem, +) -> bool { + let DiscoveredItem::Struct { + original_name: expected_original_name, + final_name: expected_final_name, + } = expected_item + else { + unreachable!() + }; + + let DiscoveredItem::Struct { + original_name: generated_original_name, + final_name: generated_final_name, + } = generated_item + else { + unreachable!() + }; + + if !compare_names(expected_final_name, generated_final_name) { + return false; + } + + match (expected_original_name, generated_original_name) { + (None, None) => true, + (Some(expected_original_name), Some(generated_original_name)) => { + compare_names(expected_original_name, generated_original_name) + } + _ => false, + } +} + +pub fn compare_union_info( + expected_item: &DiscoveredItem, + generated_item: &DiscoveredItem, +) -> bool { + let DiscoveredItem::Union { + original_name: expected_original_name, + final_name: expected_final_name, + } = expected_item + else { + unreachable!() + }; + + let DiscoveredItem::Union { + original_name: generated_original_name, + final_name: generated_final_name, + } = generated_item + else { + unreachable!() + }; + + if !compare_names(expected_final_name, generated_final_name) { + return false; + } + + match (expected_original_name, generated_original_name) { + (None, None) => true, + (Some(expected_original_name), Some(generated_original_name)) => { + compare_names(expected_original_name, generated_original_name) + } + _ => false, + } +} + +pub fn compare_enum_info( + expected_item: &DiscoveredItem, + generated_item: &DiscoveredItem, +) -> bool { + let DiscoveredItem::Enum { + final_name: expected_final_name, + } = expected_item + else { + unreachable!() + }; + + let DiscoveredItem::Enum { + final_name: generated_final_name, + } = generated_item + else { + unreachable!() + }; + + if !compare_names(expected_final_name, generated_final_name) { + return false; + } + true +} + +pub fn compare_alias_info( + expected_item: &DiscoveredItem, + generated_item: &DiscoveredItem, + expected: &ExpectationMap, + generated: &ItemCache, + expected_filename: &str, +) -> bool { + let DiscoveredItem::Alias { + alias_name: expected_alias_name, + alias_for: expected_alias_for, + } = expected_item + else { + unreachable!() + }; + + let DiscoveredItem::Alias { + alias_name: generated_alias_name, + alias_for: generated_alias_for, + } = generated_item + else { + unreachable!() + }; + + if !compare_names(expected_alias_name, generated_alias_name) { + return false; + } + + // Assumes correct test definition + let expected_aliased = expected.get(expected_alias_for).unwrap(); + + // We must have the aliased type in the cache + let Some(generated_aliased) = generated.get(generated_alias_for) else { + return false; + }; + + compare_item_info( + expected_aliased, + generated_aliased, + expected, + generated, + expected_filename, + ) +} + +pub fn compare_function_info( + expected_item: &DiscoveredItem, + generated_item: &DiscoveredItem, +) -> bool { + let DiscoveredItem::Function { + final_name: expected_final_name, + } = expected_item + else { + unreachable!() + }; + + let DiscoveredItem::Function { + final_name: generated_final_name, + } = generated_item + else { + unreachable!() + }; + + if !compare_names(expected_final_name, generated_final_name) { + return false; + } + true +} + +pub fn compare_method_info( + expected_item: &DiscoveredItem, + generated_item: &DiscoveredItem, +) -> bool { + let DiscoveredItem::Method { + final_name: expected_final_name, + parent: expected_parent, + } = expected_item + else { + unreachable!() + }; + + let DiscoveredItem::Method { + final_name: generated_final_name, + parent: generated_parent, + } = generated_item + else { + unreachable!() + }; + + if expected_parent != generated_parent { + return false; + } + + if !compare_names(expected_final_name, generated_final_name) { + return false; + } + true +} + +pub fn compare_constant_info( + expected_item: &DiscoveredItem, + generated_item: &DiscoveredItem, +) -> bool { + let DiscoveredItem::Constant { + final_name: expected_final_name, + } = expected_item + else { + unreachable!() + }; + + let DiscoveredItem::Constant { + final_name: generated_final_name, + } = generated_item + else { + unreachable!() + }; + + if !compare_names(expected_final_name, generated_final_name) { + return false; + } + true +} + +pub fn compare_variable_info( + expected_item: &DiscoveredItem, + generated_item: &DiscoveredItem, +) -> bool { + let DiscoveredItem::Variable { + final_name: expected_final_name, + } = expected_item + else { + unreachable!() + }; + + let DiscoveredItem::Variable { + final_name: generated_final_name, + } = generated_item + else { + unreachable!() + }; + + if !compare_names(expected_final_name, generated_final_name) { + return false; + } + true +} diff --git a/bindgen-tests/tests/parse_callbacks/mod.rs b/bindgen-tests/tests/parse_callbacks/mod.rs index ee31d56e49..02d7fe8316 100644 --- a/bindgen-tests/tests/parse_callbacks/mod.rs +++ b/bindgen-tests/tests/parse_callbacks/mod.rs @@ -1,3 +1,6 @@ +mod add_derives_callback; +mod item_discovery_callback; + use bindgen::callbacks::*; use bindgen::FieldVisibilityKind; @@ -52,7 +55,7 @@ impl ParseCallbacks for PrefixLinkNameParseCallback { ) -> Option { self.prefix .as_deref() - .map(|prefix| format!("{}{}", prefix, item_info.name)) + .map(|prefix| format!("{prefix}{}", item_info.name)) } } @@ -66,7 +69,7 @@ impl ParseCallbacks for EnumVariantRename { original_variant_name: &str, _variant_value: EnumVariantValue, ) -> Option { - Some(format!("RENAMED_{}", original_variant_name)) + Some(format!("RENAMED_{original_variant_name}")) } } @@ -93,8 +96,8 @@ struct FieldVisibility { } /// Implements the `field_visibility` function of the trait by checking if the -/// field name starts with `private_`. If it does it makes it private, if it -/// doesn't it makes it public, taking into account the default visibility. +/// field name starts with `private_`. If it does, it makes it private, if it +/// doesn't, it makes it public, taking into account the default visibility. impl ParseCallbacks for FieldVisibility { fn field_visibility( &self, @@ -113,6 +116,28 @@ impl ParseCallbacks for FieldVisibility { } } +#[derive(Debug)] +struct TypeVisibility; + +/// Implements the `field_visibility` function of the trait by checking the +/// type name. Depending on name prefix, it will return a different visibility. +impl ParseCallbacks for TypeVisibility { + fn field_visibility( + &self, + FieldInfo { type_name, .. }: FieldInfo, + ) -> Option { + if type_name.starts_with("private_") { + Some(FieldVisibilityKind::Private) + } else if type_name.starts_with("pubcrate_") { + Some(FieldVisibilityKind::PublicCrate) + } else if type_name.starts_with("pub_") { + Some(FieldVisibilityKind::Public) + } else { + None + } + } +} + #[derive(Debug)] pub(super) struct WrapAsVariadicFn; @@ -122,6 +147,19 @@ impl ParseCallbacks for WrapAsVariadicFn { } } +#[derive(Debug)] +pub(super) struct OperatorRename; + +impl ParseCallbacks for OperatorRename { + fn generated_name_override(&self, info: ItemInfo) -> Option { + if info.name == "operator=" { + Some("operatorequals".to_string()) + } else { + None + } + } +} + pub fn lookup(cb: &str) -> Box { match cb { "enum-variant-rename" => Box::new(EnumVariantRename), @@ -129,6 +167,8 @@ pub fn lookup(cb: &str) -> Box { Box::new(BlocklistedTypeImplementsTrait) } "wrap-as-variadic-fn" => Box::new(WrapAsVariadicFn), + "type-visibility" => Box::new(TypeVisibility), + "operator-rename" => Box::new(OperatorRename), call_back => { if let Some(prefix) = call_back.strip_prefix("remove-function-prefix-") @@ -149,7 +189,7 @@ pub fn lookup(cb: &str) -> Box { ), }) } else { - panic!("Couldn't find name ParseCallbacks: {}", cb) + panic!("Couldn't find name ParseCallbacks: {cb}") } } } diff --git a/bindgen-tests/tests/quickchecking/Cargo.toml b/bindgen-tests/tests/quickchecking/Cargo.toml index 0fafac97f3..b26ba3b392 100644 --- a/bindgen-tests/tests/quickchecking/Cargo.toml +++ b/bindgen-tests/tests/quickchecking/Cargo.toml @@ -1,10 +1,12 @@ +lints.workspace = true + [package] name = "quickchecking" description = "Bindgen property tests with quickcheck. Generate random valid C code and pass it to the csmith/predicate.py script" version = "0.0.0" publish = false -rust-version = "1.70" -edition = "2018" +rust-version.workspace = true +edition.workspace = true [lib] name = "quickchecking" @@ -15,9 +17,9 @@ name = "quickchecking" path = "src/bin.rs" [dependencies] -clap = "4" -quickcheck = "1.0" -tempfile = "3" +clap.workspace = true +quickcheck.workspace = true +tempfile.workspace = true [features] # No features by default. diff --git a/bindgen-tests/tests/quickchecking/src/bin.rs b/bindgen-tests/tests/quickchecking/src/bin.rs index fcd56652be..3072bc7b46 100644 --- a/bindgen-tests/tests/quickchecking/src/bin.rs +++ b/bindgen-tests/tests/quickchecking/src/bin.rs @@ -41,9 +41,10 @@ fn parse_tests_count(v: &str) -> Result { // Parse CLI argument input for fuzzed headers output path. fn parse_path(v: &str) -> Result { let path = PathBuf::from(v); - match path.is_dir() { - true => Ok(path), - false => Err(String::from("Provided directory path does not exist.")), + if path.is_dir() { + Ok(path) + } else { + Err(String::from("Provided directory path does not exist.")) } } @@ -105,5 +106,5 @@ fn main() { let generate_range = *matches.get_one::("range").unwrap(); let tests = *matches.get_one::("count").unwrap(); - quickchecking::test_bindgen(generate_range, tests, output_path) + quickchecking::test_bindgen(generate_range, tests, output_path); } diff --git a/bindgen-tests/tests/quickchecking/src/fuzzers.rs b/bindgen-tests/tests/quickchecking/src/fuzzers.rs index 569ed6e09b..176636f66f 100644 --- a/bindgen-tests/tests/quickchecking/src/fuzzers.rs +++ b/bindgen-tests/tests/quickchecking/src/fuzzers.rs @@ -1,7 +1,8 @@ use quickcheck::{Arbitrary, Gen}; use std::fmt; +use std::fmt::Write as _; -/// BaseTypeC is used in generation of C headers to represent the C language's +/// `BaseTypeC` is used in generation of C headers to represent the C language's /// primitive types as well as `void*`. #[derive(Debug, Clone)] pub struct BaseTypeC { @@ -9,7 +10,7 @@ pub struct BaseTypeC { pub def: String, } -/// TypeQualifierC is used in generation of C headers to represent qualifiers +/// `TypeQualifierC` is used in generation of C headers to represent qualifiers /// such as `const`. #[derive(Debug, Clone)] pub struct TypeQualifierC { @@ -17,7 +18,7 @@ pub struct TypeQualifierC { pub def: String, } -/// PointerLevelC is used in generation of C headers to represent number of +/// `PointerLevelC` is used in generation of C headers to represent number of /// `*` for pointer types. #[derive(Debug, Clone)] pub struct PointerLevelC { @@ -25,7 +26,7 @@ pub struct PointerLevelC { pub def: String, } -/// ArrayDimensionC is used in generation of C headers to represent number of +/// `ArrayDimensionC` is used in generation of C headers to represent number of /// `[]` used to define array types. #[derive(Debug, Clone)] pub struct ArrayDimensionC { @@ -33,7 +34,7 @@ pub struct ArrayDimensionC { pub def: String, } -/// BasicTypeDeclarationC is used in generation of C headers to represent +/// `BasicTypeDeclarationC` is used in generation of C headers to represent /// declarations outside of function pointers that take the form /// `BaseTypeC` + `TypeQualifierC` + `PointerLevelC` + `ident_id`. #[derive(Debug, Clone)] @@ -46,11 +47,11 @@ pub struct BasicTypeDeclarationC { pub pointer_level: PointerLevelC, /// The declaration's array dimension, i.e. [][][]. pub array_dimension: ArrayDimensionC, - /// The declaration's identifier, i.e. ident_N. + /// The declaration's identifier, i.e. `ident_N`. pub ident_id: String, } -/// StructDeclarationC is used in generation of C headers to represent the +/// `StructDeclarationC` is used in generation of C headers to represent the /// definition of a struct type. #[derive(Debug, Clone)] pub struct StructDeclarationC { @@ -58,11 +59,11 @@ pub struct StructDeclarationC { pub fields: DeclarationListC, /// The declaration's array dimension, i.e. [][][]. pub array_dimension: ArrayDimensionC, - /// The declaration's identifier, i.e. struct_N. + /// The declaration's identifier, i.e. `struct_N`. pub ident_id: String, } -/// UnionDeclarationC is used in generation of C headers to represent the +/// `UnionDeclarationC` is used in generation of C headers to represent the /// definition of a union type. #[derive(Debug, Clone)] pub struct UnionDeclarationC { @@ -70,11 +71,11 @@ pub struct UnionDeclarationC { pub fields: DeclarationListC, /// The declaration's array dimension, i.e. [][][]. pub array_dimension: ArrayDimensionC, - /// The declaration's identifier, i.e. union_N. + /// The declaration's identifier, i.e. `union_N`. pub ident_id: String, } -/// FunctionPointerDeclarationC is used in generation of C headers to represent +/// `FunctionPointerDeclarationC` is used in generation of C headers to represent /// the definition of a function pointer type. #[derive(Debug, Clone)] pub struct FunctionPointerDeclarationC { @@ -86,11 +87,11 @@ pub struct FunctionPointerDeclarationC { pub pointer_level: PointerLevelC, /// The function's parameters. pub params: ParameterListC, - /// The declaration's identifier, i.e. func_ptr_N. + /// The declaration's identifier, i.e. `func_ptr_N`. pub ident_id: String, } -/// FunctionPrototypeC is used in generation of C headers to represent the +/// `FunctionPrototypeC` is used in generation of C headers to represent the /// definition of a function prototype. #[derive(Debug, Clone)] pub struct FunctionPrototypeC { @@ -106,7 +107,7 @@ pub struct FunctionPrototypeC { pub ident_id: String, } -/// ParameterC is used in generation of C headers to represent the +/// `ParameterC` is used in generation of C headers to represent the /// definition function parameters. #[derive(Debug, Clone)] pub struct ParameterC { @@ -118,7 +119,7 @@ pub struct ParameterC { pub pointer_level: PointerLevelC, } -/// ParameterListC is used in generation of C headers to represent a list of +/// `ParameterListC` is used in generation of C headers to represent a list of /// definitions of function parameters. #[derive(Debug, Clone)] pub struct ParameterListC { @@ -126,7 +127,7 @@ pub struct ParameterListC { pub params: Vec, } -/// DeclarationC is used in generation of C headers to represent all supported +/// `DeclarationC` is used in generation of C headers to represent all supported /// C type declarations allowed in the generated header. #[derive(Debug, Clone)] pub enum DeclarationC { @@ -142,7 +143,7 @@ pub enum DeclarationC { VariableDecl(BasicTypeDeclarationC), } -/// DeclarationListC is used in generation of C headers to represent a list of +/// `DeclarationListC` is used in generation of C headers to represent a list of /// declarations. #[derive(Debug, Clone)] pub struct DeclarationListC { @@ -150,7 +151,7 @@ pub struct DeclarationListC { pub decls: Vec, } -/// HeaderC is used in generation of C headers to represent a collection of +/// `HeaderC` is used in generation of C headers to represent a collection of /// declarations. #[derive(Clone)] pub struct HeaderC { @@ -158,13 +159,13 @@ pub struct HeaderC { pub def: DeclarationListC, } -/// MakeUnique is used in generation of C headers to make declaration +/// `MakeUnique` is used in generation of C headers to make declaration /// identifiers unique by incorporating the `stamp` parameter into it's name. trait MakeUnique { fn make_unique(&mut self, stamp: usize); } -/// MakeUnique is used in generation of C headers to make DeclarationC +/// `MakeUnique` is used in generation of C headers to make `DeclarationC` /// identifiers unique. impl MakeUnique for DeclarationC { fn make_unique(&mut self, stamp: usize) { @@ -178,7 +179,7 @@ impl MakeUnique for DeclarationC { } } -/// A qucickcheck trait for describing how DeclarationC types can be +/// A qucickcheck trait for describing how `DeclarationC` types can be /// randomly generated and shrunk. impl Arbitrary for DeclarationC { fn arbitrary(g: &mut Gen) -> DeclarationC { @@ -197,20 +198,20 @@ impl Arbitrary for DeclarationC { } } -/// Enables to string and format for DeclarationC types. +/// Enables to string and format for `DeclarationC` types. impl fmt::Display for DeclarationC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - DeclarationC::FunctionPtrDecl(ref d) => write!(f, "{}", d), - DeclarationC::StructDecl(ref d) => write!(f, "{}", d), - DeclarationC::UnionDecl(ref d) => write!(f, "{}", d), - DeclarationC::VariableDecl(ref d) => write!(f, "{}", d), - DeclarationC::FunctionDecl(ref d) => write!(f, "{}", d), + DeclarationC::FunctionPtrDecl(ref d) => write!(f, "{d}"), + DeclarationC::StructDecl(ref d) => write!(f, "{d}"), + DeclarationC::UnionDecl(ref d) => write!(f, "{d}"), + DeclarationC::VariableDecl(ref d) => write!(f, "{d}"), + DeclarationC::FunctionDecl(ref d) => write!(f, "{d}"), } } } -/// A qucickcheck trait for describing how DeclarationListC types can be +/// A qucickcheck trait for describing how `DeclarationListC` types can be /// randomly generated and shrunk. impl Arbitrary for DeclarationListC { fn arbitrary(g: &mut Gen) -> DeclarationListC { @@ -220,18 +221,17 @@ impl Arbitrary for DeclarationListC { } } -/// Enables to string and format for DeclarationListC types. +/// Enables to string and format for `DeclarationListC` types. impl fmt::Display for DeclarationListC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut display = String::new(); for decl in &self.decls { - display += &format!("{}", decl); + write!(f, "{decl}")?; } - write!(f, "{}", display) + Ok(()) } } -/// A quickcheck trait for describing how BaseTypeC types can be +/// A quickcheck trait for describing how `BaseTypeC` types can be /// randomly generated and shrunk. impl Arbitrary for BaseTypeC { fn arbitrary(g: &mut Gen) -> BaseTypeC { @@ -275,14 +275,14 @@ impl Arbitrary for BaseTypeC { } } -/// Enables to string and format for BaseTypeC types, +/// Enables to string and format for `BaseTypeC` types, impl fmt::Display for BaseTypeC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.def) } } -/// A qucickcheck trait for describing how TypeQualifierC types can be +/// A qucickcheck trait for describing how `TypeQualifierC` types can be /// randomly generated and shrunk. impl Arbitrary for TypeQualifierC { fn arbitrary(g: &mut Gen) -> TypeQualifierC { @@ -293,14 +293,14 @@ impl Arbitrary for TypeQualifierC { } } -/// Enables to string and format for TypeQualifierC types. +/// Enables to string and format for `TypeQualifierC` types. impl fmt::Display for TypeQualifierC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.def) } } -/// A qucickcheck trait for describing how PointerLevelC types can be +/// A qucickcheck trait for describing how `PointerLevelC` types can be /// randomly generated and shrunk. impl Arbitrary for PointerLevelC { fn arbitrary(g: &mut Gen) -> PointerLevelC { @@ -311,14 +311,14 @@ impl Arbitrary for PointerLevelC { } } -/// Enables to string and format for PointerLevelC types. +/// Enables to string and format for `PointerLevelC` types. impl fmt::Display for PointerLevelC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.def) } } -/// A qucickcheck trait for describing how ArrayDimensionC types can be +/// A qucickcheck trait for describing how `ArrayDimensionC` types can be /// randomly generated and shrunk. impl Arbitrary for ArrayDimensionC { fn arbitrary(g: &mut Gen) -> ArrayDimensionC { @@ -330,28 +330,28 @@ impl Arbitrary for ArrayDimensionC { for _ in 1..dimensions { // 16 is an arbitrary "not too big" number for capping array size. - def += &format!("[{}]", gen_range(g, lower_bound, 16)); + let _ = write!(def, "[{}]", gen_range(g, lower_bound, 16)); } ArrayDimensionC { def } } } -/// Enables to string and format for ArrayDimensionC types. +/// Enables to string and format for `ArrayDimensionC` types. impl fmt::Display for ArrayDimensionC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.def) } } -/// MakeUnique is used in generation of C headers to make BasicTypeDeclarationC +/// `MakeUnique` is used in generation of C headers to make `BasicTypeDeclarationC` /// identifiers unique. impl MakeUnique for BasicTypeDeclarationC { fn make_unique(&mut self, stamp: usize) { - self.ident_id += &format!("_{}", stamp); + let _ = write!(self.ident_id, "_{stamp}"); } } -/// A qucickcheck trait for describing how BasicTypeDeclarationC types can be +/// A qucickcheck trait for describing how `BasicTypeDeclarationC` types can be /// randomly generated and shrunk. impl Arbitrary for BasicTypeDeclarationC { fn arbitrary(g: &mut Gen) -> BasicTypeDeclarationC { @@ -365,7 +365,7 @@ impl Arbitrary for BasicTypeDeclarationC { } } -/// Enables to string and format for BasicTypeDeclarationC types. +/// Enables to string and format for `BasicTypeDeclarationC` types. impl fmt::Display for BasicTypeDeclarationC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( @@ -380,15 +380,15 @@ impl fmt::Display for BasicTypeDeclarationC { } } -/// MakeUnique is used in generation of C headers to make StructDeclarationC +/// `MakeUnique` is used in generation of C headers to make `StructDeclarationC` /// identifiers unique. impl MakeUnique for StructDeclarationC { fn make_unique(&mut self, stamp: usize) { - self.ident_id += &format!("_{}", stamp); + let _ = write!(self.ident_id, "_{stamp}"); } } -/// A qucickcheck trait for describing how StructDeclarationC types can be +/// A qucickcheck trait for describing how `StructDeclarationC` types can be /// randomly generated and shrunk. impl Arbitrary for StructDeclarationC { fn arbitrary(g: &mut Gen) -> StructDeclarationC { @@ -417,7 +417,7 @@ impl Arbitrary for StructDeclarationC { } } -/// Enables to string and format for StructDeclarationC types. +/// Enables to string and format for `StructDeclarationC` types. impl fmt::Display for StructDeclarationC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( @@ -428,15 +428,15 @@ impl fmt::Display for StructDeclarationC { } } -/// MakeUnique is used in generation of C headers to make UnionDeclarationC +/// `MakeUnique` is used in generation of C headers to make `UnionDeclarationC` /// identifiers unique. impl MakeUnique for UnionDeclarationC { fn make_unique(&mut self, stamp: usize) { - self.ident_id += &format!("_{}", stamp); + let _ = write!(self.ident_id, "_{stamp}"); } } -/// A qucickcheck trait for describing how UnionDeclarationC types can be +/// A qucickcheck trait for describing how `UnionDeclarationC` types can be /// randomly generated and shrunk. impl Arbitrary for UnionDeclarationC { fn arbitrary(g: &mut Gen) -> UnionDeclarationC { @@ -465,7 +465,7 @@ impl Arbitrary for UnionDeclarationC { } } -/// Enables to string and format for UnionDeclarationC types. +/// Enables to string and format for `UnionDeclarationC` types. impl fmt::Display for UnionDeclarationC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( @@ -476,15 +476,15 @@ impl fmt::Display for UnionDeclarationC { } } -/// MakeUnique is used in generation of C headers to make -/// FunctionPointerDeclarationC identifiers unique. +/// `MakeUnique` is used in generation of C headers to make +/// `FunctionPointerDeclarationC` identifiers unique. impl MakeUnique for FunctionPointerDeclarationC { fn make_unique(&mut self, stamp: usize) { - self.ident_id += &format!("_{}", stamp); + let _ = write!(self.ident_id, "_{stamp}"); } } -/// A qucickcheck trait for describing how FunctionPointerDeclarationC types can +/// A qucickcheck trait for describing how `FunctionPointerDeclarationC` types can /// be randomly generated and shrunk. impl Arbitrary for FunctionPointerDeclarationC { fn arbitrary(g: &mut Gen) -> FunctionPointerDeclarationC { @@ -498,7 +498,7 @@ impl Arbitrary for FunctionPointerDeclarationC { } } -/// Enables to string and format for FunctionPointerDeclarationC types. +/// Enables to string and format for `FunctionPointerDeclarationC` types. impl fmt::Display for FunctionPointerDeclarationC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( @@ -513,15 +513,15 @@ impl fmt::Display for FunctionPointerDeclarationC { } } -/// MakeUnique is used in generation of C headers to make FunctionPrototypeC +/// `MakeUnique` is used in generation of C headers to make `FunctionPrototypeC` /// identifiers unique. impl MakeUnique for FunctionPrototypeC { fn make_unique(&mut self, stamp: usize) { - self.ident_id += &format!("_{}", stamp); + let _ = write!(self.ident_id, "_{stamp}"); } } -/// A qucickcheck trait for describing how FunctionPrototypeC types can be +/// A qucickcheck trait for describing how `FunctionPrototypeC` types can be /// randomly generated and shrunk. impl Arbitrary for FunctionPrototypeC { fn arbitrary(g: &mut Gen) -> FunctionPrototypeC { @@ -535,7 +535,7 @@ impl Arbitrary for FunctionPrototypeC { } } -/// Enables to string and format for FunctionPrototypeC types. +/// Enables to string and format for `FunctionPrototypeC` types. impl fmt::Display for FunctionPrototypeC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( @@ -550,7 +550,7 @@ impl fmt::Display for FunctionPrototypeC { } } -/// A qucickcheck trait for describing how ParameterC types can be +/// A qucickcheck trait for describing how `ParameterC` types can be /// randomly generated and shrunk. impl Arbitrary for ParameterC { fn arbitrary(g: &mut Gen) -> ParameterC { @@ -562,7 +562,7 @@ impl Arbitrary for ParameterC { } } -/// Enables to string and format for ParameterC types. +/// Enables to string and format for `ParameterC` types. impl fmt::Display for ParameterC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( @@ -573,7 +573,7 @@ impl fmt::Display for ParameterC { } } -/// A qucickcheck trait for describing how ParameterListC types can be +/// A qucickcheck trait for describing how `ParameterListC` types can be /// randomly generated and shrunk. impl Arbitrary for ParameterListC { fn arbitrary(g: &mut Gen) -> ParameterListC { @@ -583,21 +583,20 @@ impl Arbitrary for ParameterListC { } } -/// Enables to string and format for ParameterListC types. +/// Enables to string and format for `ParameterListC` types. impl fmt::Display for ParameterListC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut display = String::new(); for (i, p) in self.params.iter().enumerate() { match i { - 0 => display += &format!("{}", p), - _ => display += &format!(",{}", p), + 0 => write!(f, "{p}")?, + _ => write!(f, ",{p}")?, } } - write!(f, "{}", display) + Ok(()) } } -/// A qucickcheck trait for describing how HeaderC types can be +/// A qucickcheck trait for describing how `HeaderC` types can be /// randomly generated and shrunk. impl Arbitrary for HeaderC { fn arbitrary(g: &mut Gen) -> HeaderC { @@ -609,14 +608,13 @@ impl Arbitrary for HeaderC { } } -/// Enables to string and format for HeaderC types. +/// Enables to string and format for `HeaderC` types. impl fmt::Display for HeaderC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut display = String::new(); for decl in &self.def.decls { - display += &format!("{}", decl); + write!(f, "{decl}")?; } - write!(f, "{}", display) + Ok(()) } } @@ -624,7 +622,7 @@ impl fmt::Display for HeaderC { /// generated C code rather than the data structures that contain it. impl fmt::Debug for HeaderC { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self) + write!(f, "{self}") } } diff --git a/bindgen-tests/tests/quickchecking/src/lib.rs b/bindgen-tests/tests/quickchecking/src/lib.rs index d23ea792aa..7567a3bea6 100644 --- a/bindgen-tests/tests/quickchecking/src/lib.rs +++ b/bindgen-tests/tests/quickchecking/src/lib.rs @@ -6,13 +6,10 @@ //! use quickcheck::{Arbitrary, Gen}; //! use quickchecking::fuzzers; //! -//! fn main() { -//! let generate_range: usize = 10; // Determines things like the length of -//! // arbitrary vectors generated. -//! let header = fuzzers::HeaderC::arbitrary( -//! &mut Gen::new(generate_range)); -//! println!("{}", header); -//! } +//! let generate_range: usize = 10; // Determines things like the length of +//! // arbitrary vectors generated. +//! let header = fuzzers::HeaderC::arbitrary(&mut Gen::new(generate_range)); +//! println!("{header}"); //! ``` #![deny(missing_docs)] @@ -40,7 +37,7 @@ static CONTEXT: Mutex = Mutex::new(Context { output_path: None }); // Passes fuzzed header to the `csmith-fuzzing/predicate.py` script, returns // output of the associated command. fn run_predicate_script( - header: fuzzers::HeaderC, + header: &fuzzers::HeaderC, ) -> Result> { let dir = Builder::new().prefix("bindgen_prop").tempdir()?; let header_path = dir.path().join("prop_test.h"); @@ -80,11 +77,12 @@ fn run_predicate_script( // Generatable property. Pass generated headers off to run through the // `csmith-fuzzing/predicate.py` script. Success is measured by the success // status of that command. +#[allow(clippy::needless_pass_by_value)] fn bindgen_prop(header: fuzzers::HeaderC) -> TestResult { - match run_predicate_script(header) { + match run_predicate_script(&header) { Ok(o) => TestResult::from_bool(o.status.success()), Err(e) => { - println!("{:?}", e); + println!("{e:?}"); TestResult::from_bool(false) } } @@ -106,5 +104,5 @@ pub fn test_bindgen( QuickCheck::new() .tests(tests) .gen(Gen::new(generate_range)) - .quickcheck(bindgen_prop as fn(fuzzers::HeaderC) -> TestResult) + .quickcheck(bindgen_prop as fn(fuzzers::HeaderC) -> TestResult); } diff --git a/bindgen-tests/tests/tests.rs b/bindgen-tests/tests/tests.rs index 14988e463f..6e3c358d3e 100644 --- a/bindgen-tests/tests/tests.rs +++ b/bindgen-tests/tests/tests.rs @@ -7,10 +7,7 @@ use std::fs; use std::io::{BufRead, BufReader, Error, ErrorKind, Read, Write}; use std::path::{Path, PathBuf}; -use crate::options::builder_from_flags; - -#[path = "../../bindgen-cli/options.rs"] -mod options; +use bindgen::builder_from_flags; mod parse_callbacks; @@ -29,9 +26,10 @@ fn should_overwrite_expected() -> bool { if var == "1" { return true; } - if var != "0" && var != "" { - panic!("Invalid value of BINDGEN_OVERWRITE_EXPECTED"); - } + assert!( + var == "0" || var.is_empty(), + "Invalid value of BINDGEN_OVERWRITE_EXPECTED" + ); } false } @@ -43,9 +41,9 @@ fn error_diff_mismatch( filename: &Path, ) -> Result<(), Error> { println!("diff expected generated"); - println!("--- expected: {:?}", filename); + println!("--- expected: {}", filename.display()); if let Some(header) = header { - println!("+++ generated from: {:?}", header); + println!("+++ generated from: {}", header.display()); } show_diff(expected, actual); @@ -58,9 +56,10 @@ fn error_diff_mismatch( if let Some(var) = env::var_os("BINDGEN_TESTS_DIFFTOOL") { //usecase: var = "meld" -> You can hand check differences - let name = match filename.components().last() { - Some(std::path::Component::Normal(name)) => name, - _ => panic!("Why is the header variable so weird?"), + let Some(std::path::Component::Normal(name)) = + filename.components().next_back() + else { + panic!("Why is the header variable so weird?") }; let actual_result_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join(name); @@ -156,9 +155,9 @@ fn compare_generated_header( } else if maj >= 9 { "9".to_owned() } else { - format!("{}.{}", maj, min) + format!("{maj}.{min}") }; - expectation.push(format!("libclang-{}", version_str)); + expectation.push(format!("libclang-{version_str}")); } } } @@ -184,11 +183,10 @@ fn compare_generated_header( } None => panic!( "missing test expectation file and/or '__testing_only_libclang_$VERSION' \ - feature for header '{}'; looking for expectation file at '{:?}'", + feature for header '{}'; looking for expectation file at '{looked_at:?}'", header.display(), - looked_at, ), - }; + } let (builder, roundtrip_builder) = builder.into_builder(check_roundtrip)?; @@ -197,7 +195,7 @@ fn compare_generated_header( Ok(bindings) => format_code(bindings.to_string()).map_err(|err| { Error::new( ErrorKind::Other, - format!("Cannot parse the generated bindings: {}", err), + format!("Cannot parse the generated bindings: {err}"), ) })?, Err(_) => "/* error generating bindings */\n".into(), @@ -222,7 +220,7 @@ fn compare_generated_header( if let Err(e) = compare_generated_header(header, roundtrip_builder, false) { - return Err(Error::new(ErrorKind::Other, format!("Checking CLI flags roundtrip errored! You probably need to fix Builder::command_line_flags. {}", e))); + return Err(Error::new(ErrorKind::Other, format!("Checking CLI flags roundtrip errored! You probably need to fix Builder::command_line_flags. {e}"))); } } @@ -362,7 +360,7 @@ macro_rules! test_header { }); if let Err(err) = result { - panic!("{}", err); + panic!("{err}"); } } }; @@ -374,7 +372,7 @@ include!(concat!(env!("OUT_DIR"), "/tests.rs")); #[test] #[cfg_attr(target_os = "windows", ignore)] fn test_clang_env_args() { - std::env::set_var( + env::set_var( "BINDGEN_EXTRA_CLANG_ARGS", "-D_ENV_ONE=1 -D_ENV_TWO=\"2 -DNOT_THREE=1\"", ); @@ -393,10 +391,10 @@ fn test_clang_env_args() { let actual = format_code(actual).unwrap(); let expected = format_code( - "extern \"C\" { + "unsafe extern \"C\" { pub static x: [::std::os::raw::c_int; 1usize]; } -extern \"C\" { +unsafe extern \"C\" { pub static y: [::std::os::raw::c_int; 1usize]; } ", @@ -419,7 +417,7 @@ fn test_header_contents() { let actual = format_code(actual).unwrap(); let expected = format_code( - "extern \"C\" { + "unsafe extern \"C\" { pub fn foo(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; } ", @@ -515,10 +513,10 @@ fn test_multiple_header_contents() { let actual = format_code(actual).unwrap(); let expected = format_code( - "extern \"C\" { + "unsafe extern \"C\" { pub fn foo2(b: *const ::std::os::raw::c_char) -> f32; } -extern \"C\" { +unsafe extern \"C\" { pub fn foo(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; } ", @@ -584,29 +582,28 @@ fn test_macro_fallback_non_system_dir() { let actual = format_code(actual).unwrap(); - let (expected_filename, expected) = match clang_version().parsed { - Some((9, _)) => { - let expected_filename = concat!( - env!("CARGO_MANIFEST_DIR"), - "/tests/expectations/tests/libclang-9/macro_fallback_non_system_dir.rs", - ); - let expected = include_str!(concat!( - env!("CARGO_MANIFEST_DIR"), - "/tests/expectations/tests/libclang-9/macro_fallback_non_system_dir.rs", - )); - (expected_filename, expected) - } - _ => { - let expected_filename = concat!( - env!("CARGO_MANIFEST_DIR"), - "/tests/expectations/tests/test_macro_fallback_non_system_dir.rs", - ); - let expected = include_str!(concat!( - env!("CARGO_MANIFEST_DIR"), - "/tests/expectations/tests/test_macro_fallback_non_system_dir.rs", - )); - (expected_filename, expected) - } + let (expected_filename, expected) = if let Some((9, _)) = + clang_version().parsed + { + let expected_filename = concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/expectations/tests/libclang-9/macro_fallback_non_system_dir.rs", + ); + let expected = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/expectations/tests/libclang-9/macro_fallback_non_system_dir.rs", + )); + (expected_filename, expected) + } else { + let expected_filename = concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/expectations/tests/test_macro_fallback_non_system_dir.rs", + ); + let expected = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/expectations/tests/test_macro_fallback_non_system_dir.rs", + )); + (expected_filename, expected) }; let expected = format_code(expected).unwrap(); if expected != actual { @@ -656,8 +653,8 @@ fn emit_depfile() { builder.into_builder(check_roundtrip).unwrap(); let _bindings = builder.generate().unwrap(); - let observed = std::fs::read_to_string(observed_depfile).unwrap(); - let expected = std::fs::read_to_string(expected_depfile).unwrap(); + let observed = fs::read_to_string(observed_depfile).unwrap(); + let expected = fs::read_to_string(expected_depfile).unwrap(); assert_eq!(observed.trim(), expected.trim()); } @@ -697,7 +694,7 @@ fn dump_preprocessed_input() { ); } -fn build_flags_output_helper(builder: &bindgen::Builder) { +fn build_flags_output_helper(builder: &Builder) { let mut command_line_flags = builder.command_line_flags(); command_line_flags.insert(0, "bindgen".to_string()); @@ -706,17 +703,16 @@ fn build_flags_output_helper(builder: &bindgen::Builder) { .map(|x| format!("{}", shlex::try_quote(x).unwrap())) .collect(); let flags_str = flags_quoted.join(" "); - println!("{}", flags_str); + println!("{flags_str}"); let (builder, _output, _verbose) = - crate::options::builder_from_flags(command_line_flags.into_iter()) - .unwrap(); + builder_from_flags(command_line_flags.into_iter()).unwrap(); builder.generate().expect("failed to generate bindings"); } #[test] fn commandline_multiple_headers() { - let bindings = bindgen::Builder::default() + let bindings = Builder::default() .header("tests/headers/char.h") .header("tests/headers/func_ptr.h") .header("tests/headers/16-byte-alignment.h"); @@ -728,21 +724,39 @@ fn test_wrap_static_fns() { // This test is for testing diffs of the generated C source and header files // TODO: If another such feature is added, convert this test into a more generic // test that looks at `tests/headers/generated` directory. + + // aarch64-linux has a bug, remove custom source when it is solved: + // https://github.com/rust-lang/rust-bindgen/issues/3234 + let wrap_static_fns_c_name = + if cfg!(all(target_arch = "aarch64", target_os = "linux")) { + "wrap_static_fns_aarch64_linux" + } else { + "wrap_static_fns" + }; + let expect_path = PathBuf::from("tests/expectations/tests/generated") - .join("wrap_static_fns"); + .join(wrap_static_fns_c_name); println!("In path is ::: {}", expect_path.display()); let generated_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("wrap_static_fns"); println!("Out path is ::: {}", generated_path.display()); - let _bindings = Builder::default() + #[allow(unused_mut)] + let mut builder = Builder::default() .header("tests/headers/wrap-static-fns.h") .wrap_static_fns(true) .wrap_static_fns_path(generated_path.display().to_string()) - .parse_callbacks(Box::new(parse_callbacks::WrapAsVariadicFn)) - .generate() - .expect("Failed to generate bindings"); + .parse_callbacks(Box::new(parse_callbacks::WrapAsVariadicFn)); + + // aarch64-linux has a bug, remove when it is solved: + // https://github.com/rust-lang/rust-bindgen/issues/3234 + #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + { + builder = builder.clang_arg("-DDISABLE_VA"); + } + + builder.generate().expect("Failed to generate bindings"); let expected_c = fs::read_to_string(expect_path.with_extension("c")) .expect("Could not read generated wrap_static_fns.c"); diff --git a/bindgen/Cargo.toml b/bindgen/Cargo.toml index cad94d0c16..478574edb3 100644 --- a/bindgen/Cargo.toml +++ b/bindgen/Cargo.toml @@ -1,9 +1,11 @@ +lints.workspace = true + [package] authors = [ - "Jyun-Yan You ", - "Emilio Cobos Álvarez ", - "Nick Fitzgerald ", - "The Servo project developers", + "Jyun-Yan You ", + "Emilio Cobos Álvarez ", + "Nick Fitzgerald ", + "The Servo project developers", ] description = "Automatically generates Rust FFI bindings to C and C++ libraries." keywords = ["bindings", "ffi", "code-generation"] @@ -14,44 +16,43 @@ readme = "../README.md" repository = "https://github.com/rust-lang/rust-bindgen" documentation = "https://docs.rs/bindgen" homepage = "https://rust-lang.github.io/rust-bindgen/" -version = "0.70.1" -edition = "2018" +version = "0.72.0" build = "build.rs" -# If you change this, also update README.md and msrv in .github/workflows/bindgen.yml -rust-version = "1.70.0" +rust-version.workspace = true +edition.workspace = true [lib] name = "bindgen" path = "lib.rs" [dependencies] -annotate-snippets = { version = "0.11.4", optional = true } -bitflags = "2.2.1" -cexpr = "0.6" -clang-sys = { version = "1", features = ["clang_11_0"] } -itertools = { version = ">=0.10,<0.14", default-features = false } -log = { version = "0.4", optional = true } -prettyplease = { version = "0.2.7", optional = true, features = ["verbatim"] } -proc-macro2 = { version = "1", default-features = false } -quote = { version = "1", default-features = false } -regex = { version = "1.5.3", default-features = false, features = ["std", "unicode-perl"] } -rustc-hash = "1.0.1" -shlex = "1" -syn = { version = "2.0", features = ["full", "extra-traits", "visit-mut"] } +annotate-snippets = { workspace = true, optional = true } +bitflags.workspace = true +cexpr.workspace = true +clang-sys = { workspace = true, features = ["clang_11_0"] } +clap = { workspace = true, features = ["derive"], optional = true } +clap_complete = { workspace = true, optional = true } +itertools = { workspace = true } +log = { workspace = true, optional = true } +prettyplease = { workspace = true, optional = true, features = ["verbatim"] } +proc-macro2.workspace = true +quote.workspace = true +regex = { workspace = true, features = ["std", "unicode-perl"] } +rustc-hash.workspace = true +shlex.workspace = true +syn = { workspace = true, features = ["full", "extra-traits", "visit-mut"] } [features] default = ["logging", "prettyplease", "runtime"] logging = ["dep:log"] static = ["clang-sys/static"] runtime = ["clang-sys/runtime"] -# This feature is no longer used for anything and should be removed in bindgen 0.70 -which-rustfmt = [] experimental = ["dep:annotate-snippets"] ## The following features are for internal use and they shouldn't be used if ## you're not hacking on bindgen # Features used by `bindgen-cli` -__cli = [] +__cli = ["dep:clap", "dep:clap_complete"] # Features used for CI testing __testing_only_extra_assertions = [] __testing_only_libclang_9 = [] diff --git a/bindgen/build.rs b/bindgen/build.rs index 8407ceae8f..4fb2d3075e 100644 --- a/bindgen/build.rs +++ b/bindgen/build.rs @@ -20,10 +20,10 @@ fn main() { println!("cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS"); println!( "cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{}", - std::env::var("TARGET").unwrap() + env::var("TARGET").unwrap() ); println!( "cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{}", - std::env::var("TARGET").unwrap().replace('-', "_") + env::var("TARGET").unwrap().replace('-', "_") ); } diff --git a/bindgen/callbacks.rs b/bindgen/callbacks.rs index 43dc37d595..7967912930 100644 --- a/bindgen/callbacks.rs +++ b/bindgen/callbacks.rs @@ -4,6 +4,8 @@ pub use crate::ir::analysis::DeriveTrait; pub use crate::ir::derive::CanDerive as ImplementsTrait; pub use crate::ir::enum_ty::{EnumVariantCustomBehavior, EnumVariantValue}; pub use crate::ir::int::IntKind; +pub use cexpr::token::Kind as TokenKind; +pub use cexpr::token::Token; use std::fmt; /// An enum to allow ignoring parsing of macros. @@ -49,6 +51,9 @@ pub trait ParseCallbacks: fmt::Debug { None } + /// Modify the contents of a macro + fn modify_macro(&self, _name: &str, _tokens: &mut Vec) {} + /// The integer kind an integer macro should have, given a name and the /// value of that macro, or `None` if you want the default to be chosen. fn int_macro(&self, _name: &str, _value: i64) -> Option { @@ -89,8 +94,8 @@ pub trait ParseCallbacks: fmt::Debug { None } - /// Allows to rename an item, replacing `_original_item_name`. - fn item_name(&self, _original_item_name: &str) -> Option { + /// Allows to rename an item, replacing `_item_info.name`. + fn item_name(&self, _item_info: ItemInfo) -> Option { None } @@ -162,11 +167,106 @@ pub trait ParseCallbacks: fmt::Debug { fn wrap_as_variadic_fn(&self, _name: &str) -> Option { None } + + /// This will get called everytime an item (currently struct, union, and alias) is found with some information about it + fn new_item_found( + &self, + _id: DiscoveredItemId, + _item: DiscoveredItem, + _source_location: Option<&SourceLocation>, + ) { + } + + // TODO add callback for ResolvedTypeRef +} + +/// An identifier for a discovered item. Used to identify an aliased type (see [`DiscoveredItem::Alias`]) +#[derive(Ord, PartialOrd, PartialEq, Eq, Hash, Debug, Clone, Copy)] +pub struct DiscoveredItemId(usize); + +impl DiscoveredItemId { + /// Constructor + pub fn new(value: usize) -> Self { + Self(value) + } +} + +/// Struct passed to [`ParseCallbacks::new_item_found`] containing information about discovered +/// items (struct, union, and alias) +#[derive(Debug, Hash, Clone, Ord, PartialOrd, Eq, PartialEq)] +pub enum DiscoveredItem { + /// Represents a struct with its original name in C and its generated binding name + Struct { + /// The original name (learnt from C) of the structure + /// Can be None if the union is anonymous. + original_name: Option, + + /// The name of the generated binding + final_name: String, + }, + + /// Represents a union with its original name in C and its generated binding name + Union { + /// The original name (learnt from C) of the structure. + /// Can be None if the union is anonymous. + original_name: Option, + + /// The name of the generated binding + final_name: String, + }, + + /// Represents an alias like a typedef + /// ```c + /// typedef struct MyStruct { + /// ... + /// } StructAlias; + /// ``` + /// Here, the name of the alias is `StructAlias` and it's an alias for `MyStruct` + Alias { + /// The name of the alias in C (`StructAlias`) + alias_name: String, + + /// The identifier of the discovered type + alias_for: DiscoveredItemId, + }, + + /// Represents an enum. + Enum { + /// The final name of the generated binding + final_name: String, + }, + + /// A function or method. + Function { + /// The final name used. + final_name: String, + }, + + /// A method. + Method { + /// The final name used. + final_name: String, + + /// Type to which this method belongs. + parent: DiscoveredItemId, + }, // modules, etc. + + /// A constant. + Constant { + /// The final name of the generated binding + final_name: String, + }, + + /// A variable. + Variable { + /// The final name of the generated binding + final_name: String, + }, } /// Relevant information about a type to which new derive attributes will be added using /// [`ParseCallbacks::add_derives`]. -#[derive(Debug)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[non_exhaustive] pub struct DeriveInfo<'a> { /// The name of the type. @@ -177,7 +277,7 @@ pub struct DeriveInfo<'a> { /// Relevant information about a type to which new attributes will be added using /// [`ParseCallbacks::add_attributes`]. -#[derive(Debug)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[non_exhaustive] pub struct AttributeInfo<'a> { /// The name of the type. @@ -198,6 +298,7 @@ pub enum TypeKind { } /// A struct providing information about the item being passed to [`ParseCallbacks::generated_name_override`]. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[non_exhaustive] pub struct ItemInfo<'a> { /// The name of the item @@ -206,9 +307,14 @@ pub struct ItemInfo<'a> { pub kind: ItemKind, } -/// An enum indicating the kind of item for an ItemInfo. +/// An enum indicating the kind of item for an `ItemInfo`. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[non_exhaustive] pub enum ItemKind { + /// A module + Module, + /// A type + Type, /// A Function Function, /// A Variable @@ -217,11 +323,27 @@ pub enum ItemKind { /// Relevant information about a field for which visibility can be determined using /// [`ParseCallbacks::field_visibility`]. -#[derive(Debug)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[non_exhaustive] pub struct FieldInfo<'a> { /// The name of the type. pub type_name: &'a str, /// The name of the field. pub field_name: &'a str, + /// The name of the type of the field. + pub field_type_name: Option<&'a str>, +} + +/// Location in the source code. Roughly equivalent to the same type +/// within `clang_sys`. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct SourceLocation { + /// Line number. + pub line: usize, + /// Column number within line. + pub col: usize, + /// Byte offset within file. + pub byte_offset: usize, + /// Filename, if known. + pub file_name: Option, } diff --git a/bindgen/clang.rs b/bindgen/clang.rs index e585fb31bd..9e614da9f8 100644 --- a/bindgen/clang.rs +++ b/bindgen/clang.rs @@ -216,10 +216,10 @@ impl Cursor { }) .or_else(|| { let canonical = self.canonical(); - if canonical != *self { - canonical.num_template_args() - } else { + if canonical == *self { None + } else { + canonical.num_template_args() } }) } @@ -494,7 +494,7 @@ impl Cursor { where Visitor: FnMut(Cursor) -> CXChildVisitResult, { - let data = &mut visitor as *mut Visitor; + let data = ptr::addr_of_mut!(visitor); unsafe { clang_visitChildren(self.x, visit_children::, data.cast()); } @@ -788,7 +788,7 @@ impl Cursor { let found_attr = &mut found_attrs[idx]; if !*found_attr { // `attr.name` and` attr.token_kind` are checked against unexposed attributes only. - if attr.kind.map_or(false, |k| k == kind) || + if attr.kind == Some(kind) || (kind == CXCursor_UnexposedAttr && cur.tokens().iter().any(|t| { t.kind == attr.token_kind && @@ -878,7 +878,7 @@ impl Cursor { /// Is the cursor's referent publicly accessible in C++? /// - /// Returns true if self.access_specifier() is `CX_CXXPublic` or + /// Returns true if `self.access_specifier()` is `CX_CXXPublic` or /// `CX_CXXInvalidAccessSpecifier`. pub(crate) fn public_accessible(&self) -> bool { let access = self.access_specifier(); @@ -945,7 +945,7 @@ impl Cursor { } /// Gets the tokens that correspond to that cursor. - pub(crate) fn tokens(&self) -> RawTokens { + pub(crate) fn tokens(&self) -> RawTokens<'_> { RawTokens::new(self) } @@ -957,19 +957,22 @@ impl Cursor { .collect() } - /// Obtain the real path name of a cursor of InclusionDirective kind. + /// Obtain the real path name of a cursor of `InclusionDirective` kind. /// /// Returns None if the cursor does not include a file, otherwise the file's full name pub(crate) fn get_included_file_name(&self) -> Option { - let file = unsafe { clang_sys::clang_getIncludedFile(self.x) }; + let file = unsafe { clang_getIncludedFile(self.x) }; if file.is_null() { None } else { - Some(unsafe { - cxstring_into_string(clang_sys::clang_getFileName(file)) - }) + Some(unsafe { cxstring_into_string(clang_getFileName(file)) }) } } + + /// Is this cursor's referent a namespace that is inline? + pub(crate) fn is_inline_namespace(&self) -> bool { + unsafe { clang_Cursor_isInlineNamespace(self.x) != 0 } + } } /// A struct that owns the tokenizer result from a given cursor. @@ -1003,7 +1006,7 @@ impl<'a> RawTokens<'a> { } /// Get an iterator over these tokens. - pub(crate) fn iter(&self) -> ClangTokenIterator { + pub(crate) fn iter(&self) -> ClangTokenIterator<'_> { ClangTokenIterator { tu: self.tu, raw: self.as_slice().iter(), @@ -1011,7 +1014,7 @@ impl<'a> RawTokens<'a> { } } -impl<'a> Drop for RawTokens<'a> { +impl Drop for RawTokens<'_> { fn drop(&mut self) { if !self.tokens.is_null() { unsafe { @@ -1042,13 +1045,11 @@ pub(crate) struct ClangToken { impl ClangToken { /// Get the token spelling, without being converted to utf-8. pub(crate) fn spelling(&self) -> &[u8] { - let c_str = unsafe { - CStr::from_ptr(clang_getCString(self.spelling) as *const _) - }; + let c_str = unsafe { CStr::from_ptr(clang_getCString(self.spelling)) }; c_str.to_bytes() } - /// Converts a ClangToken to a `cexpr` token if possible. + /// Converts a `ClangToken` to a `cexpr` token if possible. pub(crate) fn as_cexpr_token(&self) -> Option { use cexpr::token; @@ -1061,7 +1062,7 @@ impl ClangToken { // expressions, so we strip them down here. CXToken_Comment => return None, _ => { - warn!("Found unexpected token kind: {:?}", self); + warn!("Found unexpected token kind: {self:?}"); return None; } }; @@ -1085,7 +1086,7 @@ pub(crate) struct ClangTokenIterator<'a> { raw: slice::Iter<'a, CXToken>, } -impl<'a> Iterator for ClangTokenIterator<'a> { +impl Iterator for ClangTokenIterator<'_> { type Item = ClangToken; fn next(&mut self) -> Option { @@ -1095,9 +1096,9 @@ impl<'a> Iterator for ClangTokenIterator<'a> { let spelling = clang_getTokenSpelling(self.tu, *raw); let extent = clang_getTokenExtent(self.tu, *raw); Some(ClangToken { - kind, - extent, spelling, + extent, + kind, }) } } @@ -1107,10 +1108,8 @@ impl<'a> Iterator for ClangTokenIterator<'a> { /// (including '_') and does not start with a digit. pub(crate) fn is_valid_identifier(name: &str) -> bool { let mut chars = name.chars(); - let first_valid = chars - .next() - .map(|c| c.is_alphabetic() || c == '_') - .unwrap_or(false); + let first_valid = + chars.next().is_some_and(|c| c.is_alphabetic() || c == '_'); first_valid && chars.all(|c| c.is_alphanumeric() || c == '_') } @@ -1123,7 +1122,7 @@ extern "C" fn visit_children( where Visitor: FnMut(Cursor) -> CXChildVisitResult, { - let func: &mut Visitor = unsafe { &mut *(data as *mut Visitor) }; + let func: &mut Visitor = unsafe { &mut *data.cast::() }; let child = Cursor { x: cur }; (*func)(child) @@ -1139,7 +1138,7 @@ impl Eq for Cursor {} impl Hash for Cursor { fn hash(&self, state: &mut H) { - unsafe { clang_hashCursor(self.x) }.hash(state) + unsafe { clang_hashCursor(self.x) }.hash(state); } } @@ -1212,11 +1211,11 @@ impl Type { /// Get a cursor pointing to this type's declaration. pub(crate) fn declaration(&self) -> Cursor { - unsafe { - Cursor { - x: clang_getTypeDeclaration(self.x), - } - } + let decl = Cursor { + x: unsafe { clang_getTypeDeclaration(self.x) }, + }; + // Prior to clang 22, the declaration pointed to the definition. + decl.definition().unwrap_or(decl) } /// Get the canonical declaration of this type, if it is available. @@ -1442,10 +1441,10 @@ impl Type { /// elements. pub(crate) fn num_elements(&self) -> Option { let num_elements_returned = unsafe { clang_getNumElements(self.x) }; - if num_elements_returned != -1 { - Some(num_elements_returned as usize) - } else { + if num_elements_returned == -1 { None + } else { + Some(num_elements_returned as usize) } } @@ -1517,7 +1516,7 @@ impl Type { // Yep, the spelling of this containing type-parameter is extremely // nasty... But can happen in . Unfortunately I couldn't // reduce it enough :( - self.template_args().map_or(false, |args| args.len() > 0) && + self.template_args().is_some_and(|args| args.len() > 0) && !matches!( self.declaration().kind(), CXCursor_ClassTemplatePartialSpecialization | @@ -1631,7 +1630,7 @@ impl fmt::Display for SourceLocation { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let (file, line, col, _) = self.location(); if let Some(name) = file.name() { - write!(f, "{}:{}:{}", name, line, col) + write!(f, "{name}:{line}:{col}") } else { "builtin definitions".fmt(f) } @@ -1640,7 +1639,7 @@ impl fmt::Display for SourceLocation { impl fmt::Debug for SourceLocation { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self) + write!(f, "{self}") } } @@ -1760,9 +1759,9 @@ impl File { fn cxstring_to_string_leaky(s: CXString) -> String { if s.data.is_null() { - return "".to_owned(); + return String::new(); } - let c_str = unsafe { CStr::from_ptr(clang_getCString(s) as *const _) }; + let c_str = unsafe { CStr::from_ptr(clang_getCString(s)) }; c_str.to_string_lossy().into_owned() } @@ -1788,7 +1787,7 @@ impl Index { pub(crate) fn new(pch: bool, diag: bool) -> Index { unsafe { Index { - x: clang_createIndex(pch as c_int, diag as c_int), + x: clang_createIndex(c_int::from(pch), c_int::from(diag)), } } } @@ -1881,9 +1880,7 @@ impl TranslationUnit { /// Save a translation unit to the given file. pub(crate) fn save(&mut self, file: &str) -> Result<(), CXSaveError> { - let file = if let Ok(cstring) = CString::new(file) { - cstring - } else { + let Ok(file) = CString::new(file) else { return Err(CXSaveError_Unknown); }; let ret = unsafe { @@ -1917,7 +1914,6 @@ impl Drop for TranslationUnit { /// Translation unit used for macro fallback parsing pub(crate) struct FallbackTranslationUnit { file_path: String, - header_path: String, pch_path: String, idx: Box, tu: TranslationUnit, @@ -1933,7 +1929,6 @@ impl FallbackTranslationUnit { /// Create a new fallback translation unit pub(crate) fn new( file: String, - header_path: String, pch_path: String, c_args: &[Box], ) -> Option { @@ -1955,7 +1950,6 @@ impl FallbackTranslationUnit { )?; Some(FallbackTranslationUnit { file_path: file, - header_path, pch_path, tu: f_translation_unit, idx: f_index, @@ -1994,7 +1988,6 @@ impl FallbackTranslationUnit { impl Drop for FallbackTranslationUnit { fn drop(&mut self) { let _ = std::fs::remove_file(&self.file_path); - let _ = std::fs::remove_file(&self.header_path); let _ = std::fs::remove_file(&self.pch_path); } } @@ -2085,26 +2078,25 @@ pub(crate) fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { let prefix = prefix.as_ref(); print_indent( depth, - format!(" {}kind = {}", prefix, kind_to_str(c.kind())), + format!(" {prefix}kind = {}", kind_to_str(c.kind())), ); print_indent( depth, - format!(" {}spelling = \"{}\"", prefix, c.spelling()), + format!(" {prefix}spelling = \"{}\"", c.spelling()), ); - print_indent(depth, format!(" {}location = {}", prefix, c.location())); + print_indent(depth, format!(" {prefix}location = {}", c.location())); print_indent( depth, - format!(" {}is-definition? {}", prefix, c.is_definition()), + format!(" {prefix}is-definition? {}", c.is_definition()), ); print_indent( depth, - format!(" {}is-declaration? {}", prefix, c.is_declaration()), + format!(" {prefix}is-declaration? {}", c.is_declaration()), ); print_indent( depth, format!( - " {}is-inlined-function? {}", - prefix, + " {prefix}is-inlined-function? {}", c.is_inlined_function() ), ); @@ -2113,23 +2105,19 @@ pub(crate) fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { if templ_kind != CXCursor_NoDeclFound { print_indent( depth, - format!( - " {}template-kind = {}", - prefix, - kind_to_str(templ_kind) - ), + format!(" {prefix}template-kind = {}", kind_to_str(templ_kind)), ); } if let Some(usr) = c.usr() { - print_indent(depth, format!(" {}usr = \"{}\"", prefix, usr)); + print_indent(depth, format!(" {prefix}usr = \"{usr}\"")); } if let Ok(num) = c.num_args() { - print_indent(depth, format!(" {}number-of-args = {}", prefix, num)); + print_indent(depth, format!(" {prefix}number-of-args = {num}")); } if let Some(num) = c.num_template_args() { print_indent( depth, - format!(" {}number-of-template-args = {}", prefix, num), + format!(" {prefix}number-of-template-args = {num}"), ); } @@ -2138,28 +2126,28 @@ pub(crate) fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { Some(w) => w.to_string(), None => "".to_string(), }; - print_indent(depth, format!(" {}bit-width = {}", prefix, width)); + print_indent(depth, format!(" {prefix}bit-width = {width}")); } if let Some(ty) = c.enum_type() { print_indent( depth, - format!(" {}enum-type = {}", prefix, type_to_str(ty.kind())), + format!(" {prefix}enum-type = {}", type_to_str(ty.kind())), ); } if let Some(val) = c.enum_val_signed() { - print_indent(depth, format!(" {}enum-val = {}", prefix, val)); + print_indent(depth, format!(" {prefix}enum-val = {val}")); } if let Some(ty) = c.typedef_type() { print_indent( depth, - format!(" {}typedef-type = {}", prefix, type_to_str(ty.kind())), + format!(" {prefix}typedef-type = {}", type_to_str(ty.kind())), ); } if let Some(ty) = c.ret_type() { print_indent( depth, - format!(" {}ret-type = {}", prefix, type_to_str(ty.kind())), + format!(" {prefix}ret-type = {}", type_to_str(ty.kind())), ); } @@ -2209,16 +2197,16 @@ pub(crate) fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { let prefix = prefix.as_ref(); let kind = ty.kind(); - print_indent(depth, format!(" {}kind = {}", prefix, type_to_str(kind))); + print_indent(depth, format!(" {prefix}kind = {}", type_to_str(kind))); if kind == CXType_Invalid { return; } - print_indent(depth, format!(" {}cconv = {}", prefix, ty.call_conv())); + print_indent(depth, format!(" {prefix}cconv = {}", ty.call_conv())); print_indent( depth, - format!(" {}spelling = \"{}\"", prefix, ty.spelling()), + format!(" {prefix}spelling = \"{}\"", ty.spelling()), ); let num_template_args = unsafe { clang_Type_getNumTemplateArguments(ty.x) }; @@ -2226,20 +2214,16 @@ pub(crate) fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { print_indent( depth, format!( - " {}number-of-template-args = {}", - prefix, num_template_args + " {prefix}number-of-template-args = {num_template_args}" ), ); } if let Some(num) = ty.num_elements() { - print_indent( - depth, - format!(" {}number-of-elements = {}", prefix, num), - ); + print_indent(depth, format!(" {prefix}number-of-elements = {num}")); } print_indent( depth, - format!(" {}is-variadic? {}", prefix, ty.is_variadic()), + format!(" {prefix}is-variadic? {}", ty.is_variadic()), ); let canonical = ty.canonical_type(); @@ -2367,10 +2351,11 @@ impl EvalResult { if unsafe { clang_EvalResult_isUnsignedInt(self.x) } != 0 { let value = unsafe { clang_EvalResult_getAsUnsigned(self.x) }; - if value > i64::MAX as c_ulonglong { + if value > u64::MAX as c_ulonglong { return None; } + // Do a wrapping cast to i64. This will be losslessly cast back to u64 later. return Some(value as i64); } diff --git a/bindgen/codegen/bitfield_unit.rs b/bindgen/codegen/bitfield_unit.rs index 73ec2bd629..8be311e311 100644 --- a/bindgen/codegen/bitfield_unit.rs +++ b/bindgen/codegen/bitfield_unit.rs @@ -16,12 +16,7 @@ where Storage: AsRef<[u8]> + AsMut<[u8]>, { #[inline] - pub fn get_bit(&self, index: usize) -> bool { - debug_assert!(index / 8 < self.storage.as_ref().len()); - - let byte_index = index / 8; - let byte = self.storage.as_ref()[byte_index]; - + fn extract_bit(byte: u8, index: usize) -> bool { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -34,12 +29,30 @@ where } #[inline] - pub fn set_bit(&mut self, index: usize, val: bool) { + pub fn get_bit(&self, index: usize) -> bool { debug_assert!(index / 8 < self.storage.as_ref().len()); let byte_index = index / 8; - let byte = &mut self.storage.as_mut()[byte_index]; + let byte = self.storage.as_ref()[byte_index]; + + Self::extract_bit(byte, index) + } + + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { let bit_index = if cfg!(target_endian = "big") { 7 - (index % 8) } else { @@ -48,12 +61,35 @@ where let mask = 1 << bit_index; if val { - *byte |= mask; + byte | mask } else { - *byte &= !mask; + byte & !mask } } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + + *byte = Self::change_bit(*byte, index, val); + } + + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + + unsafe { *byte = Self::change_bit(*byte, index, val) }; + } + #[inline] pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { debug_assert!(bit_width <= 64); @@ -79,6 +115,35 @@ where val } + #[inline] + pub unsafe fn raw_get( + this: *const Self, + bit_offset: usize, + bit_width: u8, + ) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= + core::mem::size_of::() + ); + + let mut val = 0; + + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + + val + } + #[inline] pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { debug_assert!(bit_width <= 64); @@ -99,4 +164,32 @@ where self.set_bit(index + bit_offset, val_bit_is_set); } } + + #[inline] + pub unsafe fn raw_set( + this: *mut Self, + bit_offset: usize, + bit_width: u8, + val: u64, + ) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= + core::mem::size_of::() + ); + + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { + Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) + }; + } + } } diff --git a/bindgen/codegen/bitfield_unit_tests.rs b/bindgen/codegen/bitfield_unit_tests.rs index e143e4ea78..ead0ffec0c 100644 --- a/bindgen/codegen/bitfield_unit_tests.rs +++ b/bindgen/codegen/bitfield_unit_tests.rs @@ -33,7 +33,7 @@ fn bitfield_unit_get_bit() { } println!(); - println!("bits = {:?}", bits); + println!("bits = {bits:?}"); assert_eq!( bits, &[ @@ -88,8 +88,8 @@ macro_rules! bitfield_unit_get { let actual = unit.get($start, $len); println!(); - println!("expected = {:064b}", expected); - println!("actual = {:064b}", actual); + println!("expected = {expected:064b}"); + println!("actual = {actual:064b}"); assert_eq!(expected, actual); })* @@ -191,7 +191,7 @@ macro_rules! bitfield_unit_set { println!(); println!("set({}, {}, {:032b}", $start, $len, $val); println!("expected = {:064b}", $expected); - println!("actual = {:064b}", actual); + println!("actual = {actual:064b}"); assert_eq!($expected, actual); )* diff --git a/bindgen/codegen/dyngen.rs b/bindgen/codegen/dyngen.rs index 4b2749ec0c..76f3805795 100644 --- a/bindgen/codegen/dyngen.rs +++ b/bindgen/codegen/dyngen.rs @@ -14,7 +14,7 @@ pub(crate) struct DynamicItems { /// ... /// } /// ``` - struct_members: Vec, + struct_members: Vec, /// Tracks the tokens that will appear inside the library struct's implementation, e.g.: /// @@ -26,7 +26,7 @@ pub(crate) struct DynamicItems { /// } /// } /// ``` - struct_implementation: Vec, + struct_implementation: Vec, /// Tracks the initialization of the fields inside the `::new` constructor of the library /// struct, e.g.: @@ -45,7 +45,7 @@ pub(crate) struct DynamicItems { /// ... /// } /// ``` - constructor_inits: Vec, + constructor_inits: Vec, /// Tracks the information that is passed to the library struct at the end of the `::new` /// constructor, e.g.: @@ -65,7 +65,7 @@ pub(crate) struct DynamicItems { /// } /// } /// ``` - init_fields: Vec, + init_fields: Vec, } impl DynamicItems { @@ -75,14 +75,20 @@ impl DynamicItems { pub(crate) fn get_tokens( &self, - lib_ident: Ident, + lib_ident: &Ident, ctx: &BindgenContext, - ) -> proc_macro2::TokenStream { + ) -> TokenStream { let struct_members = &self.struct_members; let constructor_inits = &self.constructor_inits; let init_fields = &self.init_fields; let struct_implementation = &self.struct_implementation; + let library_new = if ctx.options().wrap_unsafe_ops { + quote!(unsafe { ::libloading::Library::new(path) }) + } else { + quote!(::libloading::Library::new(path)) + }; + let from_library = if ctx.options().wrap_unsafe_ops { quote!(unsafe { Self::from_library(library) }) } else { @@ -100,7 +106,7 @@ impl DynamicItems { path: P ) -> Result where P: AsRef<::std::ffi::OsStr> { - let library = ::libloading::Library::new(path)?; + let library = #library_new?; #from_library } @@ -124,15 +130,16 @@ impl DynamicItems { #[allow(clippy::too_many_arguments)] pub(crate) fn push_func( &mut self, - ident: Ident, + ident: &Ident, + symbol: &str, abi: ClangAbi, is_variadic: bool, is_required: bool, - args: Vec, - args_identifiers: Vec, - ret: proc_macro2::TokenStream, - ret_ty: proc_macro2::TokenStream, - attributes: Vec, + args: &[TokenStream], + args_identifiers: &[TokenStream], + ret: &TokenStream, + ret_ty: &TokenStream, + attributes: &[TokenStream], ctx: &BindgenContext, ) { if !is_variadic { @@ -175,11 +182,12 @@ impl DynamicItems { } // N.B: Unwrap the signature upon construction if it is required to be resolved. - let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string()); + let symbol_cstr = + codegen::helpers::ast_ty::cstr_expr(symbol.to_string()); let library_get = if ctx.options().wrap_unsafe_ops { - quote!(unsafe { __library.get(#ident_str) }) + quote!(unsafe { __library.get(#symbol_cstr) }) } else { - quote!(__library.get(#ident_str)) + quote!(__library.get(#symbol_cstr)) }; self.constructor_inits.push(if is_required { @@ -199,9 +207,11 @@ impl DynamicItems { pub fn push_var( &mut self, - ident: Ident, - ty: TokenStream, + ident: &Ident, + symbol: &str, + ty: &TokenStream, is_required: bool, + wrap_unsafe_ops: bool, ) { let member = if is_required { quote! { *mut #ty } @@ -224,16 +234,22 @@ impl DynamicItems { } }); - let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string()); - self.constructor_inits.push(if is_required { - quote! { - let #ident = __library.get::<*mut #ty>(#ident_str).map(|sym| *sym)?; - } + let symbol_cstr = + codegen::helpers::ast_ty::cstr_expr(symbol.to_string()); + + let library_get = if wrap_unsafe_ops { + quote!(unsafe { __library.get::<*mut #ty>(#symbol_cstr) }) } else { - quote! { - let #ident = __library.get::<*mut #ty>(#ident_str).map(|sym| *sym); - } - }); + quote!(__library.get::<*mut #ty>(#symbol_cstr)) + }; + + let qmark = if is_required { quote!(?) } else { quote!() }; + + let var_get = quote! { + let #ident = #library_get.map(|sym| *sym)#qmark; + }; + + self.constructor_inits.push(var_get); self.init_fields.push(quote! { #ident diff --git a/bindgen/codegen/error.rs b/bindgen/codegen/error.rs index 82e921d771..b82ba2aef1 100644 --- a/bindgen/codegen/error.rs +++ b/bindgen/codegen/error.rs @@ -36,12 +36,11 @@ impl fmt::Display for Error { Error::UnsupportedAbi(abi) => { write!( f, - "{} ABI is not supported by the configured Rust target.", - abi + "{abi} ABI is not supported by the configured Rust target." ) } Error::InvalidPointerSize { ty_name, ty_size, ptr_size } => { - write!(f, "The {} pointer type has size {} but the current target's pointer size is {}.", ty_name, ty_size, ptr_size) + write!(f, "The {ty_name} pointer type has size {ty_size} but the current target's pointer size is {ptr_size}.") } } } diff --git a/bindgen/codegen/helpers.rs b/bindgen/codegen/helpers.rs index 4038340100..9b86ba47b0 100644 --- a/bindgen/codegen/helpers.rs +++ b/bindgen/codegen/helpers.rs @@ -4,6 +4,7 @@ use proc_macro2::{Ident, Span}; use crate::ir::context::BindgenContext; use crate::ir::layout::Layout; +use crate::ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT; pub(crate) mod attributes { use proc_macro2::{Ident, Span, TokenStream}; @@ -19,7 +20,6 @@ pub(crate) mod attributes { pub(crate) fn repr_list(which_ones: &[&str]) -> TokenStream { let which_ones = which_ones .iter() - .cloned() .map(|one| TokenStream::from_str(one).expect("repr to be valid")); quote! { #[repr( #( #which_ones ),* )] @@ -29,7 +29,6 @@ pub(crate) mod attributes { pub(crate) fn derives(which_ones: &[&str]) -> TokenStream { let which_ones = which_ones .iter() - .cloned() .map(|one| TokenStream::from_str(one).expect("derive to be valid")); quote! { #[derive( #( #which_ones ),* )] @@ -54,7 +53,7 @@ pub(crate) mod attributes { } } - pub(crate) fn doc(comment: String) -> TokenStream { + pub(crate) fn doc(comment: &str) -> TokenStream { if comment.is_empty() { quote!() } else { @@ -68,7 +67,7 @@ pub(crate) mod attributes { let name: Cow<'_, str> = if MANGLE { name.into() } else { - format!("\u{1}{}", name).into() + format!("\u{1}{name}").into() }; quote! { @@ -77,38 +76,49 @@ pub(crate) mod attributes { } } -/// Generates a proper type for a field or type with a given `Layout`, that is, -/// a type with the correct size and alignment restrictions. -pub(crate) fn blob(ctx: &BindgenContext, layout: Layout) -> syn::Type { - let opaque = layout.opaque(); - - // FIXME(emilio, #412): We fall back to byte alignment, but there are - // some things that legitimately are more than 8-byte aligned. - // - // Eventually we should be able to `unwrap` here, but... - let ty = match opaque.known_rust_type_for_array(ctx) { - Some(ty) => ty, - None => { - warn!("Found unknown alignment on code generation!"); - syn::parse_quote! { u8 } - } - }; - - let data_len = opaque.array_size(ctx).unwrap_or(layout.size); +/// The `ffi_safe` argument should be true if this is a type that the user might +/// reasonably use, e.g. not struct padding, where the `__BindgenOpaqueArray` is +/// just noise. +/// TODO: Should this be `MaybeUninit`, since padding bytes are effectively +/// uninitialized? +pub(crate) fn blob( + ctx: &BindgenContext, + layout: Layout, + ffi_safe: bool, +) -> syn::Type { + let align = layout.align.max(1); + // For alignments <= 4, it holds that the integer type of the same size aligns to that same + // size. For bigger alignments that's not guaranteed, e.g. on x86 u64 is aligned to 4 bytes. + if align <= 4 { + let ty = Layout::known_type_for_size(align).unwrap(); + let len = layout.size / align; + return if len == 1 { + ty + } else if !ffi_safe && len <= RUST_DERIVE_IN_ARRAY_LIMIT { + syn::parse_quote! { [#ty; #len] } + } else { + ctx.generated_opaque_array(1); + if ctx.options().enable_cxx_namespaces { + syn::parse_quote! { root::__BindgenOpaqueArray<[#ty; #len]> } + } else { + syn::parse_quote! { __BindgenOpaqueArray<[#ty; #len]> } + } + }; + } - if data_len == 1 { - ty + ctx.generated_opaque_array(align); + let ident = format_ident!("__BindgenOpaqueArray{align}"); + let size = layout.size; + if ctx.options().enable_cxx_namespaces { + syn::parse_quote! { root::#ident<[u8; #size]> } } else { - syn::parse_quote! { [ #ty ; #data_len ] } + syn::parse_quote! { #ident<[u8; #size]> } } } /// Integer type of the same size as the given `Layout`. -pub(crate) fn integer_type( - ctx: &BindgenContext, - layout: Layout, -) -> Option { - Layout::known_type_for_size(ctx, layout.size) +pub(crate) fn integer_type(layout: Layout) -> Option { + Layout::known_type_for_size(layout.size) } pub(crate) const BITFIELD_UNIT: &str = "__BindgenBitfieldUnit"; @@ -131,7 +141,6 @@ pub(crate) mod ast_ty { use crate::ir::function::FunctionSig; use crate::ir::layout::Layout; use crate::ir::ty::{FloatKind, IntKind}; - use crate::RustTarget; use proc_macro2::TokenStream; use std::str::FromStr; @@ -143,9 +152,7 @@ pub(crate) mod ast_ty { syn::parse_quote! { #prefix::c_void } } None => { - if ctx.options().use_core && - ctx.options().rust_features.core_ffi_c_void - { + if ctx.options().use_core { syn::parse_quote! { ::core::ffi::c_void } } else { syn::parse_quote! { ::std::os::raw::c_void } @@ -181,6 +188,12 @@ pub(crate) mod ast_ty { match ik { IntKind::Bool => syn::parse_quote! { bool }, IntKind::Char { .. } => raw_type(ctx, "c_char"), + // The following is used only when an unusual command-line + // argument is used. bindgen_cchar16_t is not a real type; + // but this allows downstream postprocessors to distinguish + // this case and do something special for C++ bindings + // containing the C++ type char16_t. + IntKind::Char16 => syn::parse_quote! { bindgen_cchar16_t }, IntKind::SChar => raw_type(ctx, "c_schar"), IntKind::UChar => raw_type(ctx, "c_uchar"), IntKind::Short => raw_type(ctx, "c_short"), @@ -194,7 +207,7 @@ pub(crate) mod ast_ty { IntKind::WChar => { let layout = layout.expect("Couldn't compute wchar_t's layout?"); - Layout::known_type_for_size(ctx, layout.size) + Layout::known_type_for_size(layout.size) .expect("Non-representable wchar_t?") } @@ -210,7 +223,7 @@ pub(crate) mod ast_ty { syn::parse_str(name).expect("Invalid integer type.") } IntKind::U128 => { - if ctx.options().rust_features.i128_and_u128 { + if true { syn::parse_quote! { u128 } } else { // Best effort thing, but wrong alignment @@ -219,7 +232,7 @@ pub(crate) mod ast_ty { } } IntKind::I128 => { - if ctx.options().rust_features.i128_and_u128 { + if true { syn::parse_quote! { i128 } } else { syn::parse_quote! { [u64; 2] } @@ -252,28 +265,25 @@ pub(crate) mod ast_ty { (FloatKind::Float, false) => raw_type(ctx, "c_float"), (FloatKind::Double, false) => raw_type(ctx, "c_double"), (FloatKind::LongDouble, _) => { - match layout { - Some(layout) => { - match layout.size { - 4 => syn::parse_quote! { f32 }, - 8 => syn::parse_quote! { f64 }, - // TODO(emilio): If rust ever gains f128 we should - // use it here and below. - _ => super::integer_type(ctx, layout) - .unwrap_or(syn::parse_quote! { f64 }), - } - } - None => { - debug_assert!( - false, - "How didn't we know the layout for a primitive type?" - ); - syn::parse_quote! { f64 } + if let Some(layout) = layout { + match layout.size { + 4 => syn::parse_quote! { f32 }, + 8 => syn::parse_quote! { f64 }, + // TODO(emilio): If rust ever gains f128 we should + // use it here and below. + _ => super::integer_type(layout) + .unwrap_or(syn::parse_quote! { f64 }), } + } else { + debug_assert!( + false, + "How didn't we know the layout for a primitive type?" + ); + syn::parse_quote! { f64 } } } (FloatKind::Float128, _) => { - if ctx.options().rust_features.i128_and_u128 { + if true { syn::parse_quote! { u128 } } else { syn::parse_quote! { [u64; 2] } @@ -302,59 +312,27 @@ pub(crate) mod ast_ty { } } - pub(crate) fn float_expr( - ctx: &BindgenContext, - f: f64, - ) -> Result { + pub(crate) fn float_expr(f: f64) -> Result { if f.is_finite() { let val = proc_macro2::Literal::f64_unsuffixed(f); return Ok(quote!(#val)); } - let prefix = ctx.trait_prefix(); - let rust_target = ctx.options().rust_target; - if f.is_nan() { - let tokens = if rust_target >= RustTarget::Stable_1_43 { - quote! { - f64::NAN - } - } else { - quote! { - ::#prefix::f64::NAN - } - }; - return Ok(tokens); + return Ok(quote! { f64::NAN as _ }); } if f.is_infinite() { let tokens = if f.is_sign_positive() { - if rust_target >= RustTarget::Stable_1_43 { - quote! { - f64::INFINITY - } - } else { - quote! { - ::#prefix::f64::INFINITY - } - } + quote! { f64::INFINITY as _ } } else { - // Negative infinity - if rust_target >= RustTarget::Stable_1_43 { - quote! { - f64::NEG_INFINITY - } - } else { - quote! { - ::#prefix::f64::NEG_INFINITY - } - } + quote! { f64::NEG_INFINITY as _ } }; return Ok(tokens); } - warn!("Unknown non-finite float number: {:?}", f); + warn!("Unknown non-finite float number: {f:?}"); Err(()) } @@ -366,17 +344,14 @@ pub(crate) mod ast_ty { signature .argument_types() .iter() - .map(|&(ref name, _ty)| match *name { - Some(ref name) => { - let name = ctx.rust_ident(name); - quote! { #name } - } - None => { + .map(|&(ref name, _ty)| { + let name = if let Some(ref name) = *name { + ctx.rust_ident(name) + } else { unnamed_arguments += 1; - let name = - ctx.rust_ident(format!("arg{}", unnamed_arguments)); - quote! { #name } - } + ctx.rust_ident(format!("arg{unnamed_arguments}")) + }; + quote! { #name } }) .collect() } diff --git a/bindgen/codegen/impl_debug.rs b/bindgen/codegen/impl_debug.rs index 67ec214ee8..45394724de 100644 --- a/bindgen/codegen/impl_debug.rs +++ b/bindgen/codegen/impl_debug.rs @@ -1,7 +1,8 @@ use crate::ir::comp::{BitfieldUnit, CompKind, Field, FieldData, FieldMethods}; use crate::ir::context::BindgenContext; use crate::ir::item::{HasTypeParamInArray, IsOpaque, Item, ItemCanonicalName}; -use crate::ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT}; +use crate::ir::ty::TypeKind; +use std::fmt::Write as _; pub(crate) fn gen_debug_impl( ctx: &BindgenContext, @@ -10,7 +11,7 @@ pub(crate) fn gen_debug_impl( kind: CompKind, ) -> proc_macro2::TokenStream { let struct_name = item.canonical_name(ctx); - let mut format_string = format!("{} {{{{ ", struct_name); + let mut format_string = format!("{struct_name} {{{{ "); let mut tokens = vec![]; if item.is_opaque(ctx, &()) { @@ -64,7 +65,7 @@ pub(crate) trait ImplDebug<'a> { ) -> Option<(String, Vec)>; } -impl<'a> ImplDebug<'a> for FieldData { +impl ImplDebug<'_> for FieldData { type Extra = (); fn impl_debug( @@ -80,7 +81,7 @@ impl<'a> ImplDebug<'a> for FieldData { } } -impl<'a> ImplDebug<'a> for BitfieldUnit { +impl ImplDebug<'_> for BitfieldUnit { type Extra = (); fn impl_debug( @@ -96,7 +97,7 @@ impl<'a> ImplDebug<'a> for BitfieldUnit { } if let Some(bitfield_name) = bitfield.name() { - format_string.push_str(&format!("{} : {{:?}}", bitfield_name)); + let _ = write!(format_string, "{bitfield_name} : {{:?}}"); let getter_name = bitfield.getter_name(); let name_ident = ctx.rust_ident_raw(getter_name); tokens.push(quote! { @@ -125,19 +126,14 @@ impl<'a> ImplDebug<'a> for Item { return None; } - let ty = match self.as_type() { - Some(ty) => ty, - None => { - return None; - } - }; + let ty = self.as_type()?; fn debug_print( name: &str, - name_ident: proc_macro2::TokenStream, + name_ident: &proc_macro2::TokenStream, ) -> Option<(String, Vec)> { Some(( - format!("{}: {{:?}}", name), + format!("{name}: {{:?}}"), vec![quote! { self.#name_ident }], @@ -158,60 +154,39 @@ impl<'a> ImplDebug<'a> for Item { TypeKind::ObjCInterface(..) | TypeKind::ObjCId | TypeKind::Comp(..) | - TypeKind::ObjCSel => debug_print(name, quote! { #name_ident }), + TypeKind::ObjCSel => debug_print(name, "e! { #name_ident }), TypeKind::TemplateInstantiation(ref inst) => { if inst.is_opaque(ctx, self) { - Some((format!("{}: opaque", name), vec![])) + Some((format!("{name}: opaque"), vec![])) } else { - debug_print(name, quote! { #name_ident }) + debug_print(name, "e! { #name_ident }) } } // The generic is not required to implement Debug, so we can not debug print that type TypeKind::TypeParam => { - Some((format!("{}: Non-debuggable generic", name), vec![])) + Some((format!("{name}: Non-debuggable generic"), vec![])) } TypeKind::Array(_, len) => { // Generics are not required to implement Debug if self.has_type_param_in_array(ctx) { - Some(( - format!("{}: Array with length {}", name, len), - vec![], - )) - } else if len < RUST_DERIVE_IN_ARRAY_LIMIT || - ctx.options().rust_features().larger_arrays - { - // The simple case - debug_print(name, quote! { #name_ident }) - } else if ctx.options().use_core { - // There is no String in core; reducing field visibility to avoid breaking - // no_std setups. - Some((format!("{}: [...]", name), vec![])) + Some((format!("{name}: Array with length {len}"), vec![])) } else { - // Let's implement our own print function - Some(( - format!("{}: [{{}}]", name), - vec![quote! { - self.#name_ident - .iter() - .enumerate() - .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v)) - .collect::() - }], - )) + // The simple case + debug_print(name, "e! { #name_ident }) } } TypeKind::Vector(_, len) => { if ctx.options().use_core { // There is no format! in core; reducing field visibility to avoid breaking // no_std setups. - Some((format!("{}(...)", name), vec![])) + Some((format!("{name}(...)"), vec![])) } else { let self_ids = 0..len; Some(( - format!("{}({{}})", name), + format!("{name}({{}})"), vec![quote! { #(format!("{:?}", self.#self_ids)),* }], @@ -233,9 +208,9 @@ impl<'a> ImplDebug<'a> for Item { TypeKind::Function(ref sig) if !sig.function_pointers_can_derive() => { - Some((format!("{}: FunctionPointer", name), vec![])) + Some((format!("{name}: FunctionPointer"), vec![])) } - _ => debug_print(name, quote! { #name_ident }), + _ => debug_print(name, "e! { #name_ident }), } } diff --git a/bindgen/codegen/impl_partialeq.rs b/bindgen/codegen/impl_partialeq.rs index 42fabf6ad0..a8edb4773d 100644 --- a/bindgen/codegen/impl_partialeq.rs +++ b/bindgen/codegen/impl_partialeq.rs @@ -1,7 +1,7 @@ use crate::ir::comp::{CompInfo, CompKind, Field, FieldMethods}; use crate::ir::context::BindgenContext; use crate::ir::item::{IsOpaque, Item}; -use crate::ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT}; +use crate::ir::ty::TypeKind; /// Generate a manual implementation of `PartialEq` trait for the /// specified compound type. @@ -23,22 +23,14 @@ pub(crate) fn gen_partialeq_impl( &self.bindgen_union_field[..] == &other.bindgen_union_field[..] }); } else { - for base in comp_info.base_members().iter() { + for base in comp_info.base_members() { if !base.requires_storage(ctx) { continue; } let ty_item = ctx.resolve_item(base.ty); let field_name = &base.field_name; - - if ty_item.is_opaque(ctx, &()) { - let field_name = ctx.rust_ident(field_name); - tokens.push(quote! { - &self. #field_name [..] == &other. #field_name [..] - }); - } else { - tokens.push(gen_field(ctx, ty_item, field_name)); - } + tokens.push(gen_field(ctx, ty_item, field_name)); } for field in comp_info.fields() { @@ -76,7 +68,7 @@ fn gen_field( name: &str, ) -> proc_macro2::TokenStream { fn quote_equals( - name_ident: proc_macro2::Ident, + name_ident: &proc_macro2::Ident, ) -> proc_macro2::TokenStream { quote! { self.#name_ident == other.#name_ident } } @@ -100,29 +92,9 @@ fn gen_field( TypeKind::Comp(..) | TypeKind::Pointer(_) | TypeKind::Function(..) | - TypeKind::Opaque => quote_equals(name_ident), - - TypeKind::TemplateInstantiation(ref inst) => { - if inst.is_opaque(ctx, ty_item) { - quote! { - &self. #name_ident [..] == &other. #name_ident [..] - } - } else { - quote_equals(name_ident) - } - } - - TypeKind::Array(_, len) => { - if len <= RUST_DERIVE_IN_ARRAY_LIMIT || - ctx.options().rust_features().larger_arrays - { - quote_equals(name_ident) - } else { - quote! { - &self. #name_ident [..] == &other. #name_ident [..] - } - } - } + TypeKind::Array(..) | + TypeKind::TemplateInstantiation(..) | + TypeKind::Opaque => quote_equals(&name_ident), TypeKind::Vector(_, len) => { let self_ids = 0..len; let other_ids = 0..len; diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index b92f5e127a..b6615a1600 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -21,7 +21,8 @@ use self::struct_layout::StructLayoutTracker; use super::BindgenOptions; use crate::callbacks::{ - AttributeInfo, DeriveInfo, FieldInfo, TypeKind as DeriveTypeKind, + AttributeInfo, DeriveInfo, DiscoveredItem, DiscoveredItemId, FieldInfo, + TypeKind as DeriveTypeKind, }; use crate::codegen::error::Error; use crate::ir::analysis::{HasVtable, Sizedness}; @@ -82,7 +83,7 @@ impl fmt::Display for CodegenError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Serialize { msg, loc } => { - write!(f, "serialization error at {}: {}", loc, msg) + write!(f, "serialization error at {loc}: {msg}") } Self::Io(err) => err.fmt(f), } @@ -151,22 +152,16 @@ fn derives_of_item( ) -> DerivableTraits { let mut derivable_traits = DerivableTraits::empty(); - let all_template_params = item.all_template_params(ctx); - if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() { derivable_traits |= DerivableTraits::COPY; - if ctx.options().rust_features().builtin_clone_impls || - !all_template_params.is_empty() - { - // FIXME: This requires extra logic if you have a big array in a - // templated struct. The reason for this is that the magic: - // fn clone(&self) -> Self { *self } - // doesn't work for templates. - // - // It's not hard to fix though. - derivable_traits |= DerivableTraits::CLONE; - } + // FIXME: This requires extra logic if you have a big array in a + // templated struct. The reason for this is that the magic: + // fn clone(&self) -> Self { *self } + // doesn't work for templates. + // + // It's not hard to fix though. + derivable_traits |= DerivableTraits::CLONE; } else if packed { // If the struct or union is packed, deriving from Copy is required for // deriving from any other trait. @@ -204,6 +199,19 @@ fn derives_of_item( derivable_traits } +/// Appends the contents of the `custom_derives` slice to the `derives` vector, +/// ignoring duplicates and preserving order. +fn append_custom_derives<'a>( + derives: &mut Vec<&'a str>, + custom_derives: &'a [String], +) { + for custom_derive in custom_derives.iter().map(|s| s.as_str()) { + if !derives.contains(&custom_derive) { + derives.push(custom_derive); + } + } +} + impl From for Vec<&'static str> { fn from(derivable_traits: DerivableTraits) -> Vec<&'static str> { [ @@ -378,7 +386,7 @@ impl<'a> CodegenResult<'a> { } } -impl<'a> ops::Deref for CodegenResult<'a> { +impl ops::Deref for CodegenResult<'_> { type Target = Vec; fn deref(&self) -> &Self::Target { @@ -386,7 +394,7 @@ impl<'a> ops::Deref for CodegenResult<'a> { } } -impl<'a> ops::DerefMut for CodegenResult<'a> { +impl ops::DerefMut for CodegenResult<'_> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.items } @@ -499,8 +507,7 @@ impl Item { if self.is_blocklisted(ctx) || result.seen(self.id()) { debug!( "::process_before_codegen: Ignoring hidden or seen: \ - self = {:?}", - self + self = {self:?}" ); return false; } @@ -509,7 +516,7 @@ impl Item { // TODO(emilio, #453): Figure out what to do when this happens // legitimately, we could track the opaque stuff and disable the // assertion there I guess. - warn!("Found non-allowlisted item in code generation: {:?}", self); + warn!("Found non-allowlisted item in code generation: {self:?}"); } result.set_seen(self.id()); @@ -527,7 +534,7 @@ impl CodeGenerator for Item { result: &mut CodegenResult<'_>, _extra: &(), ) { - debug!("::codegen: self = {:?}", self); + debug!("::codegen: self = {self:?}"); if !self.process_before_codegen(ctx, result) { return; } @@ -559,7 +566,7 @@ impl CodeGenerator for Module { result: &mut CodegenResult<'_>, item: &Item, ) { - debug!("::codegen: item = {:?}", item); + debug!("::codegen: item = {item:?}"); let codegen_self = |result: &mut CodegenResult, found_any: &mut bool| { @@ -586,6 +593,7 @@ impl CodeGenerator for Module { if ctx.need_bindgen_complex_type() { utils::prepend_complex_type(&mut *result); } + utils::prepend_opaque_array_types(ctx, &mut *result); if result.saw_objc { utils::prepend_objc_header(ctx, &mut *result); } @@ -658,7 +666,7 @@ impl CodeGenerator for Var { item: &Item, ) { use crate::ir::var::VarType; - debug!("::codegen: item = {:?}", item); + debug!("::codegen: item = {item:?}"); debug_assert!(item.is_enabled_for_codegen(ctx)); let canonical_name = item.canonical_name(ctx); @@ -679,20 +687,21 @@ impl CodeGenerator for Var { let mut attrs = vec![]; if let Some(comment) = item.comment(ctx) { - attrs.push(attributes::doc(comment)); + attrs.push(attributes::doc(&comment)); } let var_ty = self.ty(); let ty = var_ty.to_rust_ty_or_opaque(ctx, &()); if let Some(val) = self.val() { - match *val { - VarType::Bool(val) => { - result.push(quote! { - #(#attrs)* - pub const #canonical_ident : #ty = #val ; - }); + utils::call_discovered_item_callback(ctx, item, || { + DiscoveredItem::Constant { + final_name: canonical_name.clone(), } + }); + + let const_expr = match *val { + VarType::Bool(val) => Some(val.to_token_stream()), VarType::Int(val) => { let int_kind = var_ty .into_resolver() @@ -707,10 +716,7 @@ impl CodeGenerator for Var { } else { helpers::ast_ty::uint_expr(val as _) }; - result.push(quote! { - #(#attrs)* - pub const #canonical_ident : #ty = #val ; - }); + Some(val) } VarType::String(ref bytes) => { let prefix = ctx.trait_prefix(); @@ -723,70 +729,86 @@ impl CodeGenerator for Var { let len = proc_macro2::Literal::usize_unsuffixed( cstr_bytes.len(), ); - - // TODO: Here we ignore the type we just made up, probably - // we should refactor how the variable type and ty ID work. - let array_ty = quote! { [u8; #len] }; - let cstr_ty = quote! { ::#prefix::ffi::CStr }; - - let bytes = proc_macro2::Literal::byte_string(&cstr_bytes); - - if options.generate_cstr && - rust_features.const_cstr && - CStr::from_bytes_with_nul(&cstr_bytes).is_ok() - { - result.push(quote! { - #(#attrs)* - #[allow(unsafe_code)] - pub const #canonical_ident: &#cstr_ty = unsafe { - #cstr_ty::from_bytes_with_nul_unchecked(#bytes) - }; - }); - } else { - let lifetime = if rust_features.static_lifetime_elision - { + let cstr = + if options.generate_cstr && rust_features.const_cstr { + CStr::from_bytes_with_nul(&cstr_bytes).ok() + } else { None + }; + if let Some(cstr) = cstr { + let cstr_ty = quote! { ::#prefix::ffi::CStr }; + if rust_features.literal_cstr { + let cstr = proc_macro2::Literal::c_string(cstr); + result.push(quote! { + #(#attrs)* + pub const #canonical_ident: &#cstr_ty = #cstr; + }); } else { - Some(quote! { 'static }) + let bytes = + proc_macro2::Literal::byte_string(&cstr_bytes); + result.push(quote! { + #(#attrs)* + #[allow(unsafe_code)] + pub const #canonical_ident: &#cstr_ty = unsafe { + #cstr_ty::from_bytes_with_nul_unchecked(#bytes) + }; + }); } - .into_iter(); + } else { + // TODO: Here we ignore the type we just made up, probably + // we should refactor how the variable type and ty ID work. + let array_ty = quote! { [u8; #len] }; + let bytes = + proc_macro2::Literal::byte_string(&cstr_bytes); + let lifetime = + if true { None } else { Some(quote! { 'static }) } + .into_iter(); result.push(quote! { #(#attrs)* pub const #canonical_ident: &#(#lifetime )*#array_ty = #bytes ; }); } + None } - VarType::Float(f) => { - if let Ok(expr) = helpers::ast_ty::float_expr(ctx, f) { - result.push(quote! { - #(#attrs)* - pub const #canonical_ident : #ty = #expr ; - }); - } - } - VarType::Char(c) => { - result.push(quote! { - #(#attrs)* - pub const #canonical_ident : #ty = #c ; - }); + VarType::Float(f) => helpers::ast_ty::float_expr(f).ok(), + VarType::Char(c) => Some(c.to_token_stream()), + }; + + if let Some(mut val) = const_expr { + let var_ty_item = ctx.resolve_item(var_ty); + if matches!( + var_ty_item.alias_style(ctx), + AliasVariation::NewType | AliasVariation::NewTypeDeref + ) { + val = quote! { #ty(#val) }; } + result.push(quote! { + #(#attrs)* + pub const #canonical_ident : #ty = #val ; + }); } } else { - // If necessary, apply a `#[link_name]` attribute - if let Some(link_name) = self.link_name() { - attrs.push(attributes::link_name::(link_name)); - } else { + utils::call_discovered_item_callback(ctx, item, || { + DiscoveredItem::Variable { + final_name: canonical_name.clone(), + } + }); + + let symbol: &str = self.link_name().unwrap_or_else(|| { let link_name = self.mangled_name().unwrap_or_else(|| self.name()); - if !utils::names_will_be_identical_after_mangling( + if utils::names_will_be_identical_after_mangling( &canonical_name, link_name, None, ) { + canonical_name.as_str() + } else { attrs.push(attributes::link_name::(link_name)); + link_name } - } + }); let maybe_mut = if self.is_const() { quote! {} @@ -794,8 +816,14 @@ impl CodeGenerator for Var { quote! { mut } }; + let safety = ctx + .options() + .rust_features + .unsafe_extern_blocks + .then(|| quote!(unsafe)); + let tokens = quote!( - extern "C" { + #safety extern "C" { #(#attrs)* pub static #maybe_mut #canonical_ident: #ty; } @@ -803,11 +831,14 @@ impl CodeGenerator for Var { if ctx.options().dynamic_library_name.is_some() { result.dynamic_items().push_var( - canonical_ident, - self.ty() + &canonical_ident, + symbol, + &self + .ty() .to_rust_ty_or_opaque(ctx, &()) .into_token_stream(), ctx.options().dynamic_link_require_all, + ctx.options().wrap_unsafe_ops, ); } else { result.push(tokens); @@ -826,7 +857,7 @@ impl CodeGenerator for Type { result: &mut CodegenResult<'_>, item: &Item, ) { - debug!("::codegen: item = {:?}", item); + debug!("::codegen: item = {item:?}"); debug_assert!(item.is_enabled_for_codegen(ctx)); match *self.kind() { @@ -849,7 +880,7 @@ impl CodeGenerator for Type { // it to BindgenContext::compute_allowlisted_and_codegen_items. } TypeKind::TemplateInstantiation(ref inst) => { - inst.codegen(ctx, result, item) + inst.codegen(ctx, result, item); } TypeKind::BlockPointer(inner) => { if !ctx.options().generate_block { @@ -866,14 +897,14 @@ impl CodeGenerator for Type { { utils::fnsig_block(ctx, fnsig) } else { - panic!("invalid block typedef: {:?}", inner_item) + panic!("invalid block typedef: {inner_item:?}") } }; let rust_name = ctx.rust_ident(name); let mut tokens = if let Some(comment) = item.comment(ctx) { - attributes::doc(comment) + attributes::doc(&comment) } else { quote! {} }; @@ -924,16 +955,14 @@ impl CodeGenerator for Type { assert_eq!( layout.size, ctx.target_pointer_size(), - "Target platform requires `--no-size_t-is-usize`. The size of `{}` ({}) does not match the target pointer size ({})", - spelling, + "Target platform requires `--no-size_t-is-usize`. The size of `{spelling}` ({}) does not match the target pointer size ({})", layout.size, ctx.target_pointer_size(), ); assert_eq!( layout.align, ctx.target_pointer_size(), - "Target platform requires `--no-size_t-is-usize`. The alignment of `{}` ({}) does not match the target pointer size ({})", - spelling, + "Target platform requires `--no-size_t-is-usize`. The alignment of `{spelling}` ({}) does not match the target pointer size ({})", layout.align, ctx.target_pointer_size(), ); @@ -973,8 +1002,7 @@ impl CodeGenerator for Type { if inner_canon_type.is_invalid_type_param() { warn!( "Item contained invalid named type, skipping: \ - {:?}, {:?}", - item, inner_item + {item:?}, {inner_item:?}" ); return; } @@ -982,21 +1010,22 @@ impl CodeGenerator for Type { let rust_name = ctx.rust_ident(&name); + utils::call_discovered_item_callback(ctx, item, || { + DiscoveredItem::Alias { + alias_name: rust_name.to_string(), + alias_for: DiscoveredItemId::new( + inner_item.id().as_usize(), + ), + } + }); + let mut tokens = if let Some(comment) = item.comment(ctx) { - attributes::doc(comment) + attributes::doc(&comment) } else { quote! {} }; - let alias_style = if ctx.options().type_alias.matches(&name) { - AliasVariation::TypeAlias - } else if ctx.options().new_type_alias.matches(&name) { - AliasVariation::NewType - } else if ctx.options().new_type_alias_deref.matches(&name) { - AliasVariation::NewTypeDeref - } else { - ctx.options().default_alias_style - }; + let alias_style = item.alias_style(ctx); // We prefer using `pub use` over `pub type` because of: // https://github.com/rust-lang/rust/issues/26264 @@ -1023,12 +1052,6 @@ impl CodeGenerator for Type { pub type #rust_name }, AliasVariation::NewType | AliasVariation::NewTypeDeref => { - assert!( - ctx.options().rust_features().repr_transparent, - "repr_transparent feature is required to use {:?}", - alias_style - ); - let mut attributes = vec![attributes::repr("transparent")]; let packed = false; // Types can't be packed in Rust. @@ -1045,8 +1068,7 @@ impl CodeGenerator for Type { }) }); // In most cases this will be a no-op, since custom_derives will be empty. - derives - .extend(custom_derives.iter().map(|s| s.as_str())); + append_custom_derives(&mut derives, &custom_derives); attributes.push(attributes::derives(&derives)); let custom_attributes = @@ -1079,8 +1101,7 @@ impl CodeGenerator for Type { { warn!( "Item contained invalid template \ - parameter: {:?}", - item + parameter: {item:?}" ); return; } @@ -1099,13 +1120,24 @@ impl CodeGenerator for Type { }); } - let access_spec = - access_specifier(ctx.options().default_visibility); tokens.append_all(match alias_style { AliasVariation::TypeAlias => quote! { = #inner_rust_type ; }, AliasVariation::NewType | AliasVariation::NewTypeDeref => { + let visibility = ctx + .options() + .last_callback(|cb| { + cb.field_visibility(FieldInfo { + type_name: &item.canonical_name(ctx), + field_name: "0", + field_type_name: inner_item + .expect_type() + .name(), + }) + }) + .unwrap_or(ctx.options().default_visibility); + let access_spec = access_specifier(visibility); quote! { (#access_spec #inner_rust_type) ; } @@ -1138,10 +1170,10 @@ impl CodeGenerator for Type { result.saw_objc(); } TypeKind::ObjCInterface(ref interface) => { - interface.codegen(ctx, result, item) + interface.codegen(ctx, result, item); } ref u @ TypeKind::UnresolvedTypeRef(..) => { - unreachable!("Should have been resolved after parsing {:?}!", u) + unreachable!("Should have been resolved after parsing {u:?}!") } } } @@ -1160,7 +1192,7 @@ impl<'a> Vtable<'a> { } } -impl<'a> CodeGenerator for Vtable<'a> { +impl CodeGenerator for Vtable<'_> { type Extra = Item; type Return = (); @@ -1195,10 +1227,7 @@ impl<'a> CodeGenerator for Vtable<'a> { let function_item = ctx.resolve_item(m.signature()); let function = function_item.expect_function(); let signature_item = ctx.resolve_item(function.signature()); - let signature = match signature_item.expect_type().kind() { - TypeKind::Function(ref sig) => sig, - _ => panic!("Function signature type mismatch"), - }; + let TypeKind::Function(ref signature) = signature_item.expect_type().kind() else { panic!("Function signature type mismatch") }; // FIXME: Is there a canonical name without the class prepended? let function_name = function_item.canonical_name(ctx); @@ -1225,7 +1254,7 @@ impl<'a> CodeGenerator for Vtable<'a> { pub struct #name { #( #methods ),* } - }) + }); } else { // For the cases we don't support, simply generate an empty struct. let void = helpers::ast_ty::c_void(ctx); @@ -1238,13 +1267,13 @@ impl<'a> CodeGenerator for Vtable<'a> { } } -impl<'a> ItemCanonicalName for Vtable<'a> { +impl ItemCanonicalName for Vtable<'_> { fn canonical_name(&self, ctx: &BindgenContext) -> String { format!("{}__bindgen_vtable", self.item_id.canonical_name(ctx)) } } -impl<'a> TryToRustTy for Vtable<'a> { +impl TryToRustTy for Vtable<'_> { type Extra = (); fn try_to_rust_ty( @@ -1370,7 +1399,7 @@ trait FieldCodegen<'a> { M: Extend; } -impl<'a> FieldCodegen<'a> for Field { +impl FieldCodegen<'_> for Field { type Extra = (); fn codegen( @@ -1448,7 +1477,7 @@ fn wrap_union_field_if_needed( } } -impl<'a> FieldCodegen<'a> for FieldData { +impl FieldCodegen<'_> for FieldData { type Extra = (); fn codegen( @@ -1507,7 +1536,7 @@ impl<'a> FieldCodegen<'a> for FieldData { if ctx.options().generate_comments { if let Some(raw_comment) = self.comment() { let comment = ctx.options().process_comment(raw_comment); - field = attributes::doc(comment); + field = attributes::doc(&comment); } } @@ -1531,6 +1560,7 @@ impl<'a> FieldCodegen<'a> for FieldData { cb.field_visibility(FieldInfo { type_name: &parent_item.canonical_name(ctx), field_name, + field_type_name: field_ty.name(), }) }), self.annotations(), @@ -1564,9 +1594,9 @@ impl<'a> FieldCodegen<'a> for FieldData { return; } - let getter_name = ctx.rust_ident_raw(format!("get_{}", field_name)); + let getter_name = ctx.rust_ident_raw(format!("get_{field_name}")); let mutable_getter_name = - ctx.rust_ident_raw(format!("get_{}_mut", field_name)); + ctx.rust_ident_raw(format!("get_{field_name}_mut")); methods.extend(Some(match accessor_kind { FieldAccessorKind::None => unreachable!(), @@ -1628,18 +1658,17 @@ impl Bitfield { fn extend_ctor_impl( &self, ctx: &BindgenContext, - param_name: proc_macro2::TokenStream, + param_name: &proc_macro2::TokenStream, mut ctor_impl: proc_macro2::TokenStream, ) -> proc_macro2::TokenStream { let bitfield_ty = ctx.resolve_type(self.ty()); let bitfield_ty_layout = bitfield_ty .layout(ctx) .expect("Bitfield without layout? Gah!"); - let bitfield_int_ty = helpers::integer_type(ctx, bitfield_ty_layout) - .expect( - "Should already have verified that the bitfield is \ + let bitfield_int_ty = helpers::integer_type(bitfield_ty_layout).expect( + "Should already have verified that the bitfield is \ representable as an int", - ); + ); let offset = self.offset_into_unit(); let width = self.width() as u8; @@ -1709,7 +1738,7 @@ fn compute_visibility( }) } -impl<'a> FieldCodegen<'a> for BitfieldUnit { +impl FieldCodegen<'_> for BitfieldUnit { type Extra = (); fn codegen( @@ -1749,22 +1778,6 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { } }; - { - let align_field_name = format!("_bitfield_align_{}", self.nth()); - let align_field_ident = ctx.rust_ident(align_field_name); - let align_ty = match self.layout().align { - n if n >= 8 => quote! { u64 }, - 4 => quote! { u32 }, - 2 => quote! { u16 }, - _ => quote! { u8 }, - }; - let access_spec = access_specifier(visibility_kind); - let align_field = quote! { - #access_spec #align_field_ident: [#align_ty; 0], - }; - fields.extend(Some(align_field)); - } - let unit_field_name = format!("_bitfield_{}", self.nth()); let unit_field_ident = ctx.rust_ident(&unit_field_name); @@ -1787,12 +1800,6 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { continue; } - if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT && - !ctx.options().rust_features().larger_arrays - { - continue; - } - let mut bitfield_representable_as_int = true; let mut bitfield_visibility = visibility_kind; bf.codegen( @@ -1808,6 +1815,7 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { methods, ( &unit_field_name, + &unit_field_ty, &mut bitfield_representable_as_int, &mut bitfield_visibility, ), @@ -1831,7 +1839,7 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { ctor_params.push(quote! { #param_name : #bitfield_ty }); - ctor_impl = bf.extend_ctor_impl(ctx, param_name, ctor_impl); + ctor_impl = bf.extend_ctor_impl(ctx, ¶m_name, ctor_impl); } let access_spec = access_specifier(unit_visibility); @@ -1865,6 +1873,15 @@ fn bitfield_getter_name( quote! { #name } } +fn bitfield_raw_getter_name( + ctx: &BindgenContext, + bitfield: &Bitfield, +) -> proc_macro2::TokenStream { + let name = bitfield.getter_name(); + let name = ctx.rust_ident_raw(format!("{name}_raw")); + quote! { #name } +} + fn bitfield_setter_name( ctx: &BindgenContext, bitfield: &Bitfield, @@ -1874,8 +1891,22 @@ fn bitfield_setter_name( quote! { #setter } } +fn bitfield_raw_setter_name( + ctx: &BindgenContext, + bitfield: &Bitfield, +) -> proc_macro2::TokenStream { + let setter = bitfield.setter_name(); + let setter = ctx.rust_ident_raw(format!("{setter}_raw")); + quote! { #setter } +} + impl<'a> FieldCodegen<'a> for Bitfield { - type Extra = (&'a str, &'a mut bool, &'a mut FieldVisibilityKind); + type Extra = ( + &'a str, + &'a syn::Type, + &'a mut bool, + &'a mut FieldVisibilityKind, + ); fn codegen( &self, @@ -1889,8 +1920,14 @@ impl<'a> FieldCodegen<'a> for Bitfield { struct_layout: &mut StructLayoutTracker, _fields: &mut F, methods: &mut M, - (unit_field_name, bitfield_representable_as_int, bitfield_visibility): ( + ( + unit_field_name, + unit_field_ty, + bitfield_representable_as_int, + bitfield_visibility, + ): ( &'a str, + &'a syn::Type, &mut bool, &'a mut FieldVisibilityKind, ), @@ -1901,24 +1938,24 @@ impl<'a> FieldCodegen<'a> for Bitfield { let prefix = ctx.trait_prefix(); let getter_name = bitfield_getter_name(ctx, self); let setter_name = bitfield_setter_name(ctx, self); + let raw_getter_name = bitfield_raw_getter_name(ctx, self); + let raw_setter_name = bitfield_raw_setter_name(ctx, self); let unit_field_ident = Ident::new(unit_field_name, Span::call_site()); let bitfield_ty_item = ctx.resolve_item(self.ty()); let bitfield_ty = bitfield_ty_item.expect_type(); + let bitfield_ty_ident = bitfield_ty.name(); let bitfield_ty_layout = bitfield_ty .layout(ctx) .expect("Bitfield without layout? Gah!"); let bitfield_int_ty = - match helpers::integer_type(ctx, bitfield_ty_layout) { - Some(int_ty) => { - *bitfield_representable_as_int = true; - int_ty - } - None => { - *bitfield_representable_as_int = false; - return; - } + if let Some(int_ty) = helpers::integer_type(bitfield_ty_layout) { + *bitfield_representable_as_int = true; + int_ty + } else { + *bitfield_representable_as_int = false; + return; }; let bitfield_ty = @@ -1932,6 +1969,7 @@ impl<'a> FieldCodegen<'a> for Bitfield { cb.field_visibility(FieldInfo { type_name: &parent_item.canonical_name(ctx), field_name, + field_type_name: bitfield_ty_ident, }) }) }); @@ -1968,6 +2006,32 @@ impl<'a> FieldCodegen<'a> for Bitfield { } } })); + + methods.extend(Some(quote! { + #[inline] + #access_spec unsafe fn #raw_getter_name(this: *const Self) -> #bitfield_ty { + unsafe { + ::#prefix::mem::transmute(<#unit_field_ty>::raw_get( + (*::#prefix::ptr::addr_of!((*this).#unit_field_ident)).as_ref() as *const _, + #offset, + #width, + ) as #bitfield_int_ty) + } + } + + #[inline] + #access_spec unsafe fn #raw_setter_name(this: *mut Self, val: #bitfield_ty) { + unsafe { + let val: #bitfield_int_ty = ::#prefix::mem::transmute(val); + <#unit_field_ty>::raw_set( + (*::#prefix::ptr::addr_of_mut!((*this).#unit_field_ident)).as_mut() as *mut _, + #offset, + #width, + val as u64, + ) + } + } + })); } else { methods.extend(Some(quote! { #[inline] @@ -1992,6 +2056,32 @@ impl<'a> FieldCodegen<'a> for Bitfield { } } })); + + methods.extend(Some(quote! { + #[inline] + #access_spec unsafe fn #raw_getter_name(this: *const Self) -> #bitfield_ty { + unsafe { + ::#prefix::mem::transmute(<#unit_field_ty>::raw_get( + ::#prefix::ptr::addr_of!((*this).#unit_field_ident), + #offset, + #width, + ) as #bitfield_int_ty) + } + } + + #[inline] + #access_spec unsafe fn #raw_setter_name(this: *mut Self, val: #bitfield_ty) { + unsafe { + let val: #bitfield_int_ty = ::#prefix::mem::transmute(val); + <#unit_field_ty>::raw_set( + ::#prefix::ptr::addr_of_mut!((*this).#unit_field_ident), + #offset, + #width, + val as u64, + ) + } + } + })); } } } @@ -2006,7 +2096,7 @@ impl CodeGenerator for CompInfo { result: &mut CodegenResult<'_>, item: &Item, ) { - debug!("::codegen: item = {:?}", item); + debug!("::codegen: item = {item:?}"); debug_assert!(item.is_enabled_for_codegen(ctx)); // Don't output classes with template parameters that aren't types, and @@ -2058,7 +2148,7 @@ impl CodeGenerator for CompInfo { generic_param_names.push(ident.clone()); let prefix = ctx.trait_prefix(); - let field_name = ctx.rust_ident(format!("_phantom_{}", idx)); + let field_name = ctx.rust_ident(format!("_phantom_{idx}")); fields.push(quote! { pub #field_name : ::#prefix::marker::PhantomData< ::#prefix::cell::UnsafeCell<#ident> @@ -2178,14 +2268,13 @@ impl CodeGenerator for CompInfo { if has_address { let layout = Layout::new(1, 1); - let ty = helpers::blob(ctx, Layout::new(1, 1)); struct_layout.saw_field_with_layout( "_address", layout, /* offset = */ Some(0), ); fields.push(quote! { - pub _address: #ty, + pub _address: u8, }); } } @@ -2194,14 +2283,15 @@ impl CodeGenerator for CompInfo { match layout { Some(l) => { explicit_align = Some(l.align); - - let ty = helpers::blob(ctx, l); + let ty = helpers::blob(ctx, l, false); fields.push(quote! { pub _bindgen_opaque_blob: #ty , }); } None => { - warn!("Opaque type without layout! Expect dragons!"); + if !forward_decl { + warn!("Opaque type without layout! Expect dragons!"); + } } } } else if !is_union && !zero_sized { @@ -2217,31 +2307,21 @@ impl CodeGenerator for CompInfo { packed = true; } else { explicit_align = Some(layout.align); - if !ctx.options().rust_features.repr_align { - let ty = helpers::blob( - ctx, - Layout::new(0, layout.align), - ); - fields.push(quote! { - pub __bindgen_align: #ty , - }); - } } } } } else if is_union && !forward_decl { - // TODO(emilio): It'd be nice to unify this with the struct path - // above somehow. - let layout = layout.expect("Unable to get layout information?"); - if struct_layout.requires_explicit_align(layout) { - explicit_align = Some(layout.align); - } - - if !struct_layout.is_rust_union() { - let ty = helpers::blob(ctx, layout); - fields.push(quote! { - pub bindgen_union_field: #ty , - }) + if let Some(layout) = layout { + // TODO(emilio): It'd be nice to unify this with the struct path above somehow. + if struct_layout.requires_explicit_align(layout) { + explicit_align = Some(layout.align); + } + if !struct_layout.is_rust_union() { + let ty = helpers::blob(ctx, layout, false); + fields.push(quote! { + pub bindgen_union_field: #ty, + }); + } } } @@ -2306,7 +2386,7 @@ impl CodeGenerator for CompInfo { let mut needs_partialeq_impl = false; let needs_flexarray_impl = flex_array_generic.is_some(); if let Some(comment) = item.comment(ctx) { - attributes.push(attributes::doc(comment)); + attributes.push(attributes::doc(&comment)); } // if a type has both a "packed" attribute and an "align(N)" attribute, then check if the @@ -2317,21 +2397,34 @@ impl CodeGenerator for CompInfo { self.already_packed(ctx).unwrap_or(false)) { let n = layout.map_or(1, |l| l.align); - assert!(ctx.options().rust_features().repr_packed_n || n == 1); let packed_repr = if n == 1 { "packed".to_string() } else { - format!("packed({})", n) + format!("packed({n})") }; attributes.push(attributes::repr_list(&["C", &packed_repr])); } else { attributes.push(attributes::repr("C")); } - if ctx.options().rust_features().repr_align { - if let Some(explicit) = explicit_align { - // Ensure that the struct has the correct alignment even in - // presence of alignas. + // Ensure that the struct has the correct alignment even in presence of alignas and co. + if let Some(explicit) = explicit_align { + // If we need explicit alignment and can do it, we prefer to insert a dummy field at + // the beginning of the struct. This avoids hitting + // https://github.com/rust-lang/rust-bindgen/issues/2179 + // Do it for bitfields only for now for backwards compat. + if self.has_bitfields() && explicit <= 8 { + let align_ty = match explicit { + 8 => quote! { u64 }, + 4 => quote! { u32 }, + 2 => quote! { u16 }, + _ => quote! { u8 }, + }; + let align_field = quote! { + pub _bindgen_align: [#align_ty; 0], + }; + fields.insert(0, align_field); + } else { let explicit = helpers::ast_ty::int_expr(explicit as i64); attributes.push(quote! { #[repr(align(#explicit))] @@ -2374,6 +2467,25 @@ impl CodeGenerator for CompInfo { let is_rust_union = is_union && struct_layout.is_rust_union(); + utils::call_discovered_item_callback(ctx, item, || match self.kind() { + CompKind::Struct => DiscoveredItem::Struct { + original_name: item + .kind() + .expect_type() + .name() + .map(String::from), + final_name: canonical_ident.to_string(), + }, + CompKind::Union => DiscoveredItem::Union { + original_name: item + .kind() + .expect_type() + .name() + .map(String::from), + final_name: canonical_ident.to_string(), + }, + }); + // The custom derives callback may return a list of derive attributes; // add them to the end of the list. let custom_derives = ctx.options().all_callbacks(|cb| { @@ -2387,10 +2499,10 @@ impl CodeGenerator for CompInfo { }) }); // In most cases this will be a no-op, since custom_derives will be empty. - derives.extend(custom_derives.iter().map(|s| s.as_str())); + append_custom_derives(&mut derives, &custom_derives); if !derives.is_empty() { - attributes.push(attributes::derives(&derives)) + attributes.push(attributes::derives(&derives)); } attributes.extend( @@ -2449,10 +2561,7 @@ impl CodeGenerator for CompInfo { // affect layout, so we're bad and pray to the gods for avoid sending // all the tests to shit when parsing things like max_align_t. if self.found_unknown_attr() { - warn!( - "Type {} has an unknown attribute that may affect layout", - canonical_ident - ); + warn!("Type {canonical_ident} has an unknown attribute that may affect layout"); } if all_template_params.is_empty() { @@ -2485,19 +2594,14 @@ impl CodeGenerator for CompInfo { let align_of_err = format!("Alignment of {canonical_ident}"); - let check_struct_align = if align > - ctx.target_pointer_size() && - !ctx.options().rust_features().repr_align - { - None - } else if compile_time { - Some(quote! { + let check_struct_align = if compile_time { + quote! { [#align_of_err][#align_of_expr - #align]; - }) + } } else { - Some(quote! { + quote! { assert_eq!(#align_of_expr, #align, #align_of_err); - }) + } }; let should_skip_field_offset_checks = is_opaque; @@ -2508,12 +2612,9 @@ impl CodeGenerator for CompInfo { } else { self.fields() .iter() - .filter_map(|field| match *field { - Field::DataMember(ref f) if f.name().is_some() => Some(f), - _ => None, - }) - .flat_map(|field| { - let name = field.name().unwrap(); + .filter_map(|field| { + let Field::DataMember(field) = field else { return None }; + let name = field.name()?; field.offset().map(|offset| { let field_offset = offset / 8; let field_name = ctx.rust_ident(name); @@ -2580,15 +2681,17 @@ impl CodeGenerator for CompInfo { } let mut method_names = Default::default(); + let discovered_id = DiscoveredItemId::new(item.id().as_usize()); if ctx.options().codegen_config.methods() { for method in self.methods() { - assert!(method.kind() != MethodKind::Constructor); + assert_ne!(method.kind(), MethodKind::Constructor); method.codegen_method( ctx, &mut methods, &mut method_names, result, self, + discovered_id, ); } } @@ -2607,6 +2710,7 @@ impl CodeGenerator for CompInfo { &mut method_names, result, self, + discovered_id, ); } } @@ -2620,6 +2724,7 @@ impl CodeGenerator for CompInfo { &mut method_names, result, self, + discovered_id, ); } } @@ -2643,7 +2748,7 @@ impl CodeGenerator for CompInfo { result.push(self.generate_flexarray( ctx, &canonical_ident, - flex_inner_ty, + flex_inner_ty.as_ref(), &generic_param_names, &impl_generics_labels, )); @@ -2651,21 +2756,11 @@ impl CodeGenerator for CompInfo { if needs_default_impl { let prefix = ctx.trait_prefix(); - let body = if ctx.options().rust_features().maybe_uninit { - quote! { - let mut s = ::#prefix::mem::MaybeUninit::::uninit(); - unsafe { - ::#prefix::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } - } else { - quote! { - unsafe { - let mut s: Self = ::#prefix::mem::uninitialized(); - ::#prefix::ptr::write_bytes(&mut s, 0, 1); - s - } + let body = quote! { + let mut s = ::#prefix::mem::MaybeUninit::::uninit(); + unsafe { + ::#prefix::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() } }; // Note we use `ptr::write_bytes()` instead of `mem::zeroed()` because the latter does @@ -2705,13 +2800,13 @@ impl CodeGenerator for CompInfo { item, &ty_for_impl, ) { - let partialeq_bounds = if !generic_param_names.is_empty() { + let partialeq_bounds = if generic_param_names.is_empty() { + quote! {} + } else { let bounds = generic_param_names.iter().map(|t| { quote! { #t: PartialEq } }); quote! { where #( #bounds ),* } - } else { - quote! {} }; let prefix = ctx.trait_prefix(); @@ -2738,7 +2833,7 @@ impl CompInfo { &self, ctx: &BindgenContext, canonical_ident: &Ident, - flex_inner_ty: Option, + flex_inner_ty: Option<&proc_macro2::TokenStream>, generic_param_names: &[Ident], impl_generics_labels: &proc_macro2::TokenStream, ) -> proc_macro2::TokenStream { @@ -2877,12 +2972,13 @@ impl Method { method_names: &mut HashSet, result: &mut CodegenResult<'_>, _parent: &CompInfo, + parent_id: DiscoveredItemId, ) { assert!({ let cc = &ctx.options().codegen_config; match self.kind() { MethodKind::Constructor => cc.constructors(), - MethodKind::Destructor => cc.destructors(), + MethodKind::Destructor | MethodKind::VirtualDestructor { .. } => cc.destructors(), MethodKind::Static | MethodKind::Normal | @@ -2902,10 +2998,7 @@ impl Method { } let function = function_item.expect_function(); let times_seen = function.codegen(ctx, result, function_item); - let times_seen = match times_seen { - Some(seen) => seen, - None => return, - }; + let Some(times_seen) = times_seen else { return }; let signature_item = ctx.resolve_item(function.signature()); let mut name = match self.kind() { MethodKind::Constructor => "new".into(), @@ -2913,9 +3006,10 @@ impl Method { _ => function.name().to_owned(), }; - let signature = match *signature_item.expect_type().kind() { - TypeKind::Function(ref sig) => sig, - _ => panic!("How in the world?"), + let TypeKind::Function(ref signature) = + *signature_item.expect_type().kind() + else { + panic!("How in the world?") }; let supported_abi = signature.abi(ctx, Some(&*name)).is_ok(); @@ -2934,7 +3028,7 @@ impl Method { let mut new_name; while { - new_name = format!("{}{}", name, count); + new_name = format!("{name}{count}"); method_names.contains(&new_name) } { count += 1; @@ -2945,9 +3039,16 @@ impl Method { method_names.insert(name.clone()); + utils::call_discovered_item_callback(ctx, function_item, || { + DiscoveredItem::Method { + parent: parent_id, + final_name: name.clone(), + } + }); + let mut function_name = function_item.canonical_name(ctx); if times_seen > 0 { - write!(&mut function_name, "{}", times_seen).unwrap(); + write!(&mut function_name, "{times_seen}").unwrap(); } let function_name = ctx.rust_ident(function_name); let mut args = utils::fnsig_arguments(ctx, signature); @@ -2980,24 +3081,11 @@ impl Method { // variable called `__bindgen_tmp` we're going to create. if self.is_constructor() { let prefix = ctx.trait_prefix(); - let tmp_variable_decl = if ctx - .options() - .rust_features() - .maybe_uninit - { - exprs[0] = quote! { - __bindgen_tmp.as_mut_ptr() - }; - quote! { - let mut __bindgen_tmp = ::#prefix::mem::MaybeUninit::uninit() - } - } else { - exprs[0] = quote! { - &mut __bindgen_tmp - }; - quote! { - let mut __bindgen_tmp = ::#prefix::mem::uninitialized() - } + exprs[0] = quote! { + __bindgen_tmp.as_mut_ptr() + }; + let tmp_variable_decl = quote! { + let mut __bindgen_tmp = ::#prefix::mem::MaybeUninit::uninit() }; stmts.push(tmp_variable_decl); } else if !self.is_static() { @@ -3005,7 +3093,7 @@ impl Method { exprs[0] = quote! { self }; - }; + } let call = quote! { #function_name (#( #exprs ),* ) @@ -3014,24 +3102,16 @@ impl Method { stmts.push(call); if self.is_constructor() { - stmts.push(if ctx.options().rust_features().maybe_uninit { - quote! { + stmts.push(quote! { __bindgen_tmp.assume_init() - } - } else { - quote! { - __bindgen_tmp - } - }) + }); } let block = ctx.wrap_unsafe_ops(quote! ( #( #stmts );*)); let mut attrs = vec![attributes::inline()]; - if signature.must_use() && - ctx.options().rust_features().must_use_function - { + if signature.must_use() { attrs.push(attributes::must_use()); } @@ -3050,7 +3130,7 @@ impl Method { pub enum EnumVariation { /// The code for this enum will use a Rust enum. Note that creating this in unsafe code /// (including FFI) with an invalid value will invoke undefined behaviour, whether or not - /// its marked as non_exhaustive. + /// its marked as `#[non_exhaustive]`. Rust { /// Indicates whether the generated struct should be `#[non_exhaustive]` non_exhaustive: bool, @@ -3070,14 +3150,14 @@ pub enum EnumVariation { } impl EnumVariation { - fn is_rust(&self) -> bool { - matches!(*self, EnumVariation::Rust { .. }) + fn is_rust(self) -> bool { + matches!(self, EnumVariation::Rust { .. }) } /// Both the `Const` and `ModuleConsts` variants will cause this to return /// true. - fn is_const(&self) -> bool { - matches!(*self, EnumVariation::Consts | EnumVariation::ModuleConsts) + fn is_const(self) -> bool { + matches!(self, EnumVariation::Consts | EnumVariation::ModuleConsts) } } @@ -3110,7 +3190,7 @@ impl fmt::Display for EnumVariation { } } -impl std::str::FromStr for EnumVariation { +impl FromStr for EnumVariation { type Err = std::io::Error; /// Create a `EnumVariation` from a string. @@ -3148,216 +3228,211 @@ impl std::str::FromStr for EnumVariation { } } +struct EnumBuilder { + /// Type identifier of the enum. + /// + /// This is the base name, i.e. for `ModuleConst` enums, this does not include the module name. + enum_type: Ident, + /// Attributes applying to the enum type + attrs: Vec, + /// The representation of the enum, e.g. `u32`. + repr: syn::Type, + /// The enum kind we are generating + kind: EnumBuilderKind, + /// A list of all variants this enum has. + enum_variants: Vec, +} + /// A helper type to construct different enum variations. -enum EnumBuilder<'a> { +enum EnumBuilderKind { Rust { - attrs: Vec, - ident: Ident, - tokens: proc_macro2::TokenStream, - emitted_any_variants: bool, + non_exhaustive: bool, }, NewType { - canonical_name: &'a str, - tokens: proc_macro2::TokenStream, is_bitfield: bool, is_global: bool, + /// if the enum is named or not. + is_anonymous: bool, }, Consts { - variants: Vec, + needs_typedef: bool, }, ModuleConsts { - module_name: &'a str, - module_items: Vec, + module_name: Ident, }, } -impl<'a> EnumBuilder<'a> { +impl EnumBuilder { /// Returns true if the builder is for a rustified enum. fn is_rust_enum(&self) -> bool { - matches!(*self, EnumBuilder::Rust { .. }) + matches!(self.kind, EnumBuilderKind::Rust { .. }) } /// Create a new enum given an item builder, a canonical name, a name for /// the representation, and which variation it should be generated as. fn new( - name: &'a str, - mut attrs: Vec, - repr: syn::Type, + name: &str, + attrs: Vec, + repr: &syn::Type, enum_variation: EnumVariation, has_typedef: bool, + enum_is_anonymous: bool, ) -> Self { let ident = Ident::new(name, Span::call_site()); + // For most variants this is the same + let mut enum_ty = ident.clone(); - match enum_variation { + let kind = match enum_variation { EnumVariation::NewType { is_bitfield, is_global, - } => EnumBuilder::NewType { - canonical_name: name, - tokens: quote! { - #( #attrs )* - pub struct #ident (pub #repr); - }, + } => EnumBuilderKind::NewType { is_bitfield, is_global, + is_anonymous: enum_is_anonymous, }, - EnumVariation::Rust { .. } => { - // `repr` is guaranteed to be Rustified in Enum::codegen - attrs.insert(0, quote! { #[repr( #repr )] }); - let tokens = quote!(); - EnumBuilder::Rust { - attrs, - ident, - tokens, - emitted_any_variants: false, - } + EnumVariation::Rust { non_exhaustive } => { + EnumBuilderKind::Rust { non_exhaustive } } - EnumVariation::Consts => { - let mut variants = Vec::new(); - - if !has_typedef { - variants.push(quote! { - #( #attrs )* - pub type #ident = #repr; - }); - } - - EnumBuilder::Consts { variants } - } + EnumVariation::Consts => EnumBuilderKind::Consts { + needs_typedef: !has_typedef, + }, EnumVariation::ModuleConsts => { - let ident = Ident::new( + enum_ty = Ident::new( CONSTIFIED_ENUM_MODULE_REPR_NAME, Span::call_site(), ); - let type_definition = quote! { - #( #attrs )* - pub type #ident = #repr; - }; - EnumBuilder::ModuleConsts { - module_name: name, - module_items: vec![type_definition], + EnumBuilderKind::ModuleConsts { + module_name: ident.clone(), } } + }; + EnumBuilder { + enum_type: enum_ty, + attrs, + repr: repr.clone(), + kind, + enum_variants: vec![], } } /// Add a variant to this enum. fn with_variant( - self, + mut self, ctx: &BindgenContext, variant: &EnumVariant, + variant_doc: proc_macro2::TokenStream, mangling_prefix: Option<&str>, - rust_ty: syn::Type, - result: &mut CodegenResult<'_>, + rust_ty: &syn::Type, is_ty_named: bool, ) -> Self { let variant_name = ctx.rust_mangle(variant.name()); let is_rust_enum = self.is_rust_enum(); let expr = match variant.val() { EnumVariantValue::Boolean(v) if is_rust_enum => { - helpers::ast_ty::uint_expr(v as u64) + helpers::ast_ty::uint_expr(u64::from(v)) } EnumVariantValue::Boolean(v) => quote!(#v), EnumVariantValue::Signed(v) => helpers::ast_ty::int_expr(v), EnumVariantValue::Unsigned(v) => helpers::ast_ty::uint_expr(v), }; - let mut doc = quote! {}; - if ctx.options().generate_comments { - if let Some(raw_comment) = variant.comment() { - let comment = ctx.options().process_comment(raw_comment); - doc = attributes::doc(comment); - } - } - - match self { - EnumBuilder::Rust { - attrs, - ident, - tokens, - emitted_any_variants: _, - } => { + match self.kind { + EnumBuilderKind::Rust { .. } => { let name = ctx.rust_ident(variant_name); - EnumBuilder::Rust { - attrs, - ident, - tokens: quote! { - #tokens - #doc - #name = #expr, - }, - emitted_any_variants: true, - } + self.enum_variants.push(EnumVariantInfo { + variant_name: name, + variant_doc, + value: expr, + }); + self } - EnumBuilder::NewType { - canonical_name, - is_global, - .. - } => { - if ctx.options().rust_features().associated_const && - is_ty_named && - !is_global - { - let enum_ident = ctx.rust_ident(canonical_name); - let variant_ident = ctx.rust_ident(variant_name); - - result.push(quote! { - impl #enum_ident { - #doc - pub const #variant_ident : #rust_ty = #rust_ty ( #expr ); - } - }); + EnumBuilderKind::NewType { is_global, .. } => { + let variant_ident = if is_ty_named && !is_global { + ctx.rust_ident(variant_name) } else { - let ident = ctx.rust_ident(match mangling_prefix { + ctx.rust_ident(match mangling_prefix { Some(prefix) => { - Cow::Owned(format!("{}_{}", prefix, variant_name)) + Cow::Owned(format!("{prefix}_{variant_name}")) } None => variant_name, - }); - result.push(quote! { - #doc - pub const #ident : #rust_ty = #rust_ty ( #expr ); - }); - } + }) + }; + self.enum_variants.push(EnumVariantInfo { + variant_name: variant_ident, + variant_doc, + value: quote! { #rust_ty ( #expr )}, + }); self } - EnumBuilder::Consts { .. } => { + EnumBuilderKind::Consts { .. } => { let constant_name = match mangling_prefix { Some(prefix) => { - Cow::Owned(format!("{}_{}", prefix, variant_name)) + Cow::Owned(format!("{prefix}_{variant_name}")) } None => variant_name, }; let ident = ctx.rust_ident(constant_name); - result.push(quote! { - #doc - pub const #ident : #rust_ty = #expr ; + self.enum_variants.push(EnumVariantInfo { + variant_name: ident, + variant_doc, + value: quote! { #expr }, }); self } - EnumBuilder::ModuleConsts { - module_name, - mut module_items, - } => { + EnumBuilderKind::ModuleConsts { .. } => { let name = ctx.rust_ident(variant_name); - let ty = ctx.rust_ident(CONSTIFIED_ENUM_MODULE_REPR_NAME); - module_items.push(quote! { - #doc - pub const #name : #ty = #expr ; + self.enum_variants.push(EnumVariantInfo { + variant_name: name, + variant_doc, + value: quote! { #expr }, }); + self + } + } + } + + fn newtype_bitfield_impl( + prefix: &Ident, + rust_ty: &syn::Type, + ) -> proc_macro2::TokenStream { + let rust_ty_name = &rust_ty; + quote! { + impl ::#prefix::ops::BitOr<#rust_ty> for #rust_ty { + type Output = Self; + + #[inline] + fn bitor(self, other: Self) -> Self { + #rust_ty_name(self.0 | other.0) + } + } + impl ::#prefix::ops::BitOrAssign for #rust_ty { + #[inline] + fn bitor_assign(&mut self, rhs: #rust_ty) { + self.0 |= rhs.0; + } + } + impl ::#prefix::ops::BitAnd<#rust_ty> for #rust_ty { + type Output = Self; - EnumBuilder::ModuleConsts { - module_name, - module_items, + #[inline] + fn bitand(self, other: Self) -> Self { + #rust_ty_name(self.0 & other.0) + } + } + impl ::#prefix::ops::BitAndAssign for #rust_ty { + #[inline] + fn bitand_assign(&mut self, rhs: #rust_ty) { + self.0 &= rhs.0; } } } @@ -3366,95 +3441,145 @@ impl<'a> EnumBuilder<'a> { fn build( self, ctx: &BindgenContext, - rust_ty: syn::Type, - result: &mut CodegenResult<'_>, + rust_ty: &syn::Type, ) -> proc_macro2::TokenStream { - match self { - EnumBuilder::Rust { - attrs, - ident, - tokens, - emitted_any_variants, - .. - } => { - let variants = if !emitted_any_variants { - quote!(__bindgen_cannot_repr_c_on_empty_enum = 0) - } else { - tokens - }; + let enum_ident = self.enum_type; + + // 1. Construct a list of the enum variants + let variants = match self.kind { + EnumBuilderKind::Rust { .. } => { + let mut variants = vec![]; + + for v in self.enum_variants { + let variant_doc = &v.variant_doc; + let variant_ident = &v.variant_name; + let variant_value = &v.value; + + variants.push(quote! { + #variant_doc + #variant_ident = #variant_value, + }); + } + + if variants.is_empty() { + variants.push( + quote! {__bindgen_cannot_repr_c_on_empty_enum = 0,}, + ); + } + variants + } + EnumBuilderKind::NewType { .. } => { + let mut variants = vec![]; + + for v in self.enum_variants { + let variant_doc = &v.variant_doc; + let variant_ident = &v.variant_name; + let variant_value = &v.value; + + variants.push(quote! { + #variant_doc + pub const #variant_ident: #enum_ident = #variant_value; + }); + } + variants + } + EnumBuilderKind::Consts { .. } | + EnumBuilderKind::ModuleConsts { .. } => { + let mut variants = vec![]; + + for v in self.enum_variants { + let variant_doc = &v.variant_doc; + let variant_ident = &v.variant_name; + let variant_value = &v.value; + + variants.push(quote! { + #variant_doc + pub const #variant_ident: #enum_ident = #variant_value; + }); + } + variants + } + }; + let attrs = self.attrs; + let enum_repr = &self.repr; + + // 2. Generate the enum representation + match self.kind { + EnumBuilderKind::Rust { non_exhaustive } => { + let non_exhaustive_opt = + non_exhaustive.then(attributes::non_exhaustive); quote! { + // Note: repr is on top of attrs to keep the test expectations diff small. + // a future commit could move it further down. + #[repr(#enum_repr)] + #non_exhaustive_opt #( #attrs )* - pub enum #ident { - #variants + pub enum #enum_ident { + #( #variants )* } } } - EnumBuilder::NewType { - canonical_name, - tokens, + EnumBuilderKind::NewType { is_bitfield, - .. + is_global, + is_anonymous, } => { - if !is_bitfield { - return tokens; - } - - let rust_ty_name = ctx.rust_ident_raw(canonical_name); - let prefix = ctx.trait_prefix(); - - result.push(quote! { - impl ::#prefix::ops::BitOr<#rust_ty> for #rust_ty { - type Output = Self; - - #[inline] - fn bitor(self, other: Self) -> Self { - #rust_ty_name(self.0 | other.0) - } + // There doesn't seem to be a technical reason why we generate + // anon enum variants as global constants. + // We keep this behavior to avoid breaking changes in the bindings. + let impl_variants = if is_anonymous || is_global { + quote! { + #( #variants )* } - }); - - result.push(quote! { - impl ::#prefix::ops::BitOrAssign for #rust_ty { - #[inline] - fn bitor_assign(&mut self, rhs: #rust_ty) { - self.0 |= rhs.0; + } else { + quote! { + impl #enum_ident { + #( #variants )* } } - }); + }; - result.push(quote! { - impl ::#prefix::ops::BitAnd<#rust_ty> for #rust_ty { - type Output = Self; + let prefix = ctx.trait_prefix(); + let bitfield_impl_opt = is_bitfield + .then(|| Self::newtype_bitfield_impl(&prefix, rust_ty)); - #[inline] - fn bitand(self, other: Self) -> Self { - #rust_ty_name(self.0 & other.0) - } - } - }); + quote! { + // Previously variant impls where before the enum definition. + // lets keep this as is for now, to reduce the diff in generated bindings. + #impl_variants - result.push(quote! { - impl ::#prefix::ops::BitAndAssign for #rust_ty { - #[inline] - fn bitand_assign(&mut self, rhs: #rust_ty) { - self.0 &= rhs.0; - } + #bitfield_impl_opt + + #[repr(transparent)] + #( #attrs )* + pub struct #enum_ident (pub #enum_repr); + } + } + EnumBuilderKind::Consts { needs_typedef } => { + let typedef_opt = needs_typedef.then(|| { + quote! { + #( #attrs )* + pub type #enum_ident = #enum_repr; } }); + quote! { + #( #variants )* - tokens + #typedef_opt + } } - EnumBuilder::Consts { variants, .. } => quote! { #( #variants )* }, - EnumBuilder::ModuleConsts { - module_items, - module_name, - .. - } => { - let ident = ctx.rust_ident(module_name); + EnumBuilderKind::ModuleConsts { module_name, .. } => { quote! { - pub mod #ident { - #( #module_items )* + // todo: Probably some attributes, e.g. `cfg` should apply to the `mod`. + pub mod #module_name { + #[allow(unused_imports)] + use super::*; + + #( #attrs )* + pub type #enum_ident = #enum_repr; + + #( #variants )* } } } @@ -3472,7 +3597,7 @@ impl CodeGenerator for Enum { result: &mut CodegenResult<'_>, item: &Item, ) { - debug!("::codegen: item = {:?}", item); + debug!("::codegen: item = {item:?}"); debug_assert!(item.is_enabled_for_codegen(ctx)); let name = item.canonical_name(ctx); @@ -3497,18 +3622,17 @@ impl CodeGenerator for Enum { // * the representation couldn't be determined from the C source // * it was explicitly requested as a bindgen option - let kind = match repr { - Some(repr) => match *repr.canonical_type(ctx).kind() { + let kind = if let Some(repr) = repr { + match *repr.canonical_type(ctx).kind() { TypeKind::Int(int_kind) => int_kind, _ => panic!("Unexpected type as enum repr"), - }, - None => { - warn!( - "Guessing type of enum! Forward declarations of enums \ - shouldn't be legal!" - ); - IntKind::Int } + } else { + warn!( + "Guessing type of enum! Forward declarations of enums \ + shouldn't be legal!" + ); + IntKind::Int }; let signed = kind.is_signed(); @@ -3528,8 +3652,7 @@ impl CodeGenerator for Enum { (false, 8) => IntKind::U64, _ => { warn!( - "invalid enum decl: signed: {}, size: {}", - signed, size + "invalid enum decl: signed: {signed}, size: {size}" ); IntKind::I32 } @@ -3543,31 +3666,8 @@ impl CodeGenerator for Enum { let mut attrs = vec![]; - // TODO(emilio): Delegate this to the builders? - match variation { - EnumVariation::Rust { non_exhaustive } => { - if non_exhaustive && - ctx.options().rust_features().non_exhaustive - { - attrs.push(attributes::non_exhaustive()); - } else if non_exhaustive && - !ctx.options().rust_features().non_exhaustive - { - panic!("The rust target you're using doesn't seem to support non_exhaustive enums"); - } - } - EnumVariation::NewType { .. } => { - if ctx.options().rust_features.repr_transparent { - attrs.push(attributes::repr("transparent")); - } else { - attrs.push(attributes::repr("C")); - } - } - _ => {} - }; - if let Some(comment) = item.comment(ctx) { - attrs.push(attributes::doc(comment)); + attrs.push(attributes::doc(&comment)); } if item.must_use(ctx) { @@ -3587,7 +3687,7 @@ impl CodeGenerator for Enum { DerivableTraits::EQ, ); let mut derives: Vec<_> = derives.into(); - for derive in item.annotations().derives().iter() { + for derive in item.annotations().derives() { if !derives.contains(&derive.as_str()) { derives.push(derive); } @@ -3602,7 +3702,7 @@ impl CodeGenerator for Enum { }) }); // In most cases this will be a no-op, since custom_derives will be empty. - derives.extend(custom_derives.iter().map(|s| s.as_str())); + append_custom_derives(&mut derives, &custom_derives); attrs.extend( item.annotations() @@ -3634,17 +3734,17 @@ impl CodeGenerator for Enum { // value. variant_name: &Ident, referenced_name: &Ident, - enum_rust_ty: syn::Type, + enum_rust_ty: &syn::Type, result: &mut CodegenResult<'_>, ) { let constant_name = if enum_.name().is_some() { if ctx.options().prepend_enum_name { - format!("{}_{}", enum_canonical_name, variant_name) + format!("{enum_canonical_name}_{variant_name}") } else { - format!("{}", variant_name) + format!("{variant_name}") } } else { - format!("{}", variant_name) + format!("{variant_name}") }; let constant_name = ctx.rust_ident(constant_name); @@ -3657,8 +3757,20 @@ impl CodeGenerator for Enum { let repr = repr.to_rust_ty_or_opaque(ctx, item); let has_typedef = ctx.is_enum_typedef_combo(item.id()); - let mut builder = - EnumBuilder::new(&name, attrs, repr, variation, has_typedef); + utils::call_discovered_item_callback(ctx, item, || { + DiscoveredItem::Enum { + final_name: name.clone(), + } + }); + + let mut builder = EnumBuilder::new( + &name, + attrs, + &repr, + variation, + has_typedef, + enum_ty.name().is_none(), + ); // A map where we keep a value -> variant relation. let mut seen_values = HashMap::<_, Ident>::default(); @@ -3700,28 +3812,33 @@ impl CodeGenerator for Enum { continue; } + let mut variant_doc = quote! {}; + if ctx.options().generate_comments { + if let Some(raw_comment) = variant.comment() { + let processed_comment = + ctx.options().process_comment(raw_comment); + variant_doc = attributes::doc(&processed_comment); + } + } + match seen_values.entry(variant.val()) { Entry::Occupied(ref entry) => { if variation.is_rust() { let variant_name = ctx.rust_mangle(variant.name()); - let mangled_name = - if is_toplevel || enum_ty.name().is_some() { - variant_name - } else { - let parent_name = - parent_canonical_name.as_ref().unwrap(); + let mangled_name = if is_toplevel || + enum_ty.name().is_some() + { + variant_name + } else { + let parent_name = + parent_canonical_name.as_ref().unwrap(); - Cow::Owned(format!( - "{}_{}", - parent_name, variant_name - )) - }; + Cow::Owned(format!("{parent_name}_{variant_name}")) + }; let existing_variant_name = entry.get(); // Use associated constants for named enums. - if enum_ty.name().is_some() && - ctx.options().rust_features().associated_const - { + if enum_ty.name().is_some() { let enum_canonical_name = &ident; let variant_name = ctx.rust_ident_raw(&*mangled_name); @@ -3738,7 +3855,7 @@ impl CodeGenerator for Enum { &ident, &Ident::new(&mangled_name, Span::call_site()), existing_variant_name, - enum_rust_ty.clone(), + &enum_rust_ty, result, ); } @@ -3746,9 +3863,9 @@ impl CodeGenerator for Enum { builder = builder.with_variant( ctx, variant, + variant_doc, constant_mangling_prefix, - enum_rust_ty.clone(), - result, + &enum_rust_ty, enum_ty.name().is_some(), ); } @@ -3757,9 +3874,9 @@ impl CodeGenerator for Enum { builder = builder.with_variant( ctx, variant, + variant_doc, constant_mangling_prefix, - enum_rust_ty.clone(), - result, + &enum_rust_ty, enum_ty.name().is_some(), ); @@ -3778,7 +3895,7 @@ impl CodeGenerator for Enum { parent_canonical_name.as_ref().unwrap(); Ident::new( - &format!("{}_{}", parent_name, variant_name), + &format!("{parent_name}_{variant_name}"), Span::call_site(), ) }; @@ -3789,7 +3906,7 @@ impl CodeGenerator for Enum { &ident, &mangled_name, &variant_name, - enum_rust_ty.clone(), + &enum_rust_ty, result, ); } @@ -3799,11 +3916,17 @@ impl CodeGenerator for Enum { } } - let item = builder.build(ctx, enum_rust_ty, result); + let item = builder.build(ctx, &enum_rust_ty); result.push(item); } } +struct EnumVariantInfo { + variant_name: Ident, + variant_doc: proc_macro2::TokenStream, + value: proc_macro2::TokenStream, +} + /// Enum for the default type of macro constants. #[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] pub enum MacroTypeVariation { @@ -3824,7 +3947,7 @@ impl fmt::Display for MacroTypeVariation { } } -impl std::str::FromStr for MacroTypeVariation { +impl FromStr for MacroTypeVariation { type Err = std::io::Error; /// Create a `MacroTypeVariation` from a string. @@ -3851,7 +3974,7 @@ pub enum AliasVariation { TypeAlias, /// Create a new type by wrapping the old type in a struct and using #[repr(transparent)] NewType, - /// Same as NewStruct but also impl Deref to be able to use the methods of the wrapped type + /// Same as `NewType` but also impl Deref to be able to use the methods of the wrapped type NewTypeDeref, } @@ -3867,7 +3990,7 @@ impl fmt::Display for AliasVariation { } } -impl std::str::FromStr for AliasVariation { +impl FromStr for AliasVariation { type Err = std::io::Error; /// Create an `AliasVariation` from a string. @@ -3916,7 +4039,7 @@ impl Default for NonCopyUnionStyle { } } -impl std::str::FromStr for NonCopyUnionStyle { +impl FromStr for NonCopyUnionStyle { type Err = std::io::Error; fn from_str(s: &str) -> Result { @@ -3956,7 +4079,7 @@ pub(crate) trait TryToOpaque { extra: &Self::Extra, ) -> error::Result { self.try_get_layout(ctx, extra) - .map(|layout| helpers::blob(ctx, layout)) + .map(|layout| helpers::blob(ctx, layout, true)) } } @@ -3982,7 +4105,7 @@ pub(crate) trait ToOpaque: TryToOpaque { extra: &Self::Extra, ) -> syn::Type { let layout = self.get_layout(ctx, extra); - helpers::blob(ctx, layout) + helpers::blob(ctx, layout, true) } } @@ -4033,9 +4156,9 @@ where ) -> error::Result { self.try_to_rust_ty(ctx, extra).or_else(|_| { if let Ok(layout) = self.try_get_layout(ctx, extra) { - Ok(helpers::blob(ctx, layout)) + Ok(helpers::blob(ctx, layout, true)) } else { - Err(error::Error::NoLayoutForOpaqueBlob) + Err(Error::NoLayoutForOpaqueBlob) } }) } @@ -4050,11 +4173,11 @@ where /// ### Fallible vs. Infallible Conversions to Rust Types /// /// When should one use this infallible `ToRustTyOrOpaque` trait versus the -/// fallible `TryTo{RustTy, Opaque, RustTyOrOpaque}` triats? All fallible trait +/// fallible `TryTo{RustTy, Opaque, RustTyOrOpaque}` traits? All fallible trait /// implementations that need to convert another thing into a Rust type or /// opaque blob in a nested manner should also use fallible trait methods and /// propagate failure up the stack. Only infallible functions and methods like -/// CodeGenerator implementations should use the infallible +/// `CodeGenerator` implementations should use the infallible /// `ToRustTyOrOpaque`. The further out we push error recovery, the more likely /// we are to get a usable `Layout` even if we can't generate an equivalent Rust /// type for a C++ construct. @@ -4146,7 +4269,7 @@ impl TryToOpaque for Type { ctx: &BindgenContext, _: &Item, ) -> error::Result { - self.layout(ctx).ok_or(error::Error::NoLayoutForOpaqueBlob) + self.layout(ctx).ok_or(Error::NoLayoutForOpaqueBlob) } } @@ -4272,6 +4395,12 @@ impl TryToRustTy for Type { if inner_ty.canonical_type(ctx).is_function() || is_objc_pointer { Ok(ty) + } else if ctx.options().generate_cxx_nonnull_references && + matches!(self.kind(), TypeKind::Reference(_)) + { + // It's UB to pass null values in place of C++ references + let prefix = ctx.trait_prefix(); + Ok(syn::parse_quote! { ::#prefix::ptr::NonNull<#ty> }) } else { Ok(ty.to_ptr(is_const)) } @@ -4288,7 +4417,7 @@ impl TryToRustTy for Type { Ok(syn::parse_quote! { #name }) } ref u @ TypeKind::UnresolvedTypeRef(..) => { - unreachable!("Should have been resolved after parsing {:?}!", u) + unreachable!("Should have been resolved after parsing {u:?}!") } } } @@ -4304,7 +4433,7 @@ impl TryToOpaque for TemplateInstantiation { ) -> error::Result { item.expect_type() .layout(ctx) - .ok_or(error::Error::NoLayoutForOpaqueBlob) + .ok_or(Error::NoLayoutForOpaqueBlob) } } @@ -4317,7 +4446,7 @@ impl TryToRustTy for TemplateInstantiation { item: &Item, ) -> error::Result { if self.is_opaque(ctx, item) { - return Err(error::Error::InstantiationOfOpaqueType); + return Err(Error::InstantiationOfOpaqueType); } let def = self @@ -4339,7 +4468,7 @@ impl TryToRustTy for TemplateInstantiation { // template specialization, and we've hit an instantiation of // that partial specialization. extra_assert!(def.is_opaque(ctx, &())); - return Err(error::Error::InstantiationOfOpaqueType); + return Err(Error::InstantiationOfOpaqueType); } // TODO: If the definition type is a template class/struct @@ -4391,7 +4520,7 @@ impl TryToRustTy for FunctionSig { syn::parse_quote! { unsafe extern #abi fn ( #( #arguments ),* ) #ret }, ), Err(err) => { - if matches!(err, error::Error::UnsupportedAbi(_)) { + if matches!(err, Error::UnsupportedAbi(_)) { unsupported_abi_diagnostic( self.name(), self.is_variadic(), @@ -4420,16 +4549,15 @@ impl CodeGenerator for Function { result: &mut CodegenResult<'_>, item: &Item, ) -> Self::Return { - debug!("::codegen: item = {:?}", item); + debug!("::codegen: item = {item:?}"); debug_assert!(item.is_enabled_for_codegen(ctx)); let is_internal = matches!(self.linkage(), Linkage::Internal); let signature_item = ctx.resolve_item(self.signature()); let signature = signature_item.kind().expect_type().canonical_type(ctx); - let signature = match *signature.kind() { - TypeKind::Function(ref sig) => sig, - _ => panic!("Signature kind is not a Function: {:?}", signature), + let TypeKind::Function(ref signature) = *signature.kind() else { + panic!("Signature kind is not a Function: {signature:?}") }; if is_internal { @@ -4447,18 +4575,24 @@ impl CodeGenerator for Function { } } - // Pure virtual methods have no actual symbol, so we can't generate - // something meaningful for them. - let is_dynamic_function = match self.kind() { - FunctionKind::Method(ref method_kind) - if method_kind.is_pure_virtual() => - { - return None; + let is_pure_virtual = match self.kind() { + FunctionKind::Method(ref method_kind) => { + method_kind.is_pure_virtual() } + FunctionKind::Function => false, + }; + if is_pure_virtual && !ctx.options().generate_pure_virtual_functions { + // Pure virtual methods have no actual symbol, so we can't generate + // something meaningful for them. Downstream code postprocessors + // might want to find out about them. + return None; + } + + let is_dynamic_function = match self.kind() { FunctionKind::Function => { ctx.options().dynamic_library_name.is_some() } - _ => false, + FunctionKind::Method(_) => false, }; // Similar to static member variables in a class template, we can't @@ -4486,7 +4620,7 @@ impl CodeGenerator for Function { let mut attributes = vec![]; - if ctx.options().rust_features().must_use_function { + if true { let must_use = signature.must_use() || { let ret_ty = signature .return_type() @@ -4502,12 +4636,12 @@ impl CodeGenerator for Function { } if let Some(comment) = item.comment(ctx) { - attributes.push(attributes::doc(comment)); + attributes.push(attributes::doc(&comment)); } let abi = match signature.abi(ctx, Some(name)) { Err(err) => { - if matches!(err, error::Error::UnsupportedAbi(_)) { + if matches!(err, Error::UnsupportedAbi(_)) { unsupported_abi_diagnostic( name, signature.is_variadic(), @@ -4521,8 +4655,7 @@ impl CodeGenerator for Function { } Ok(ClangAbi::Unknown(unknown_abi)) => { panic!( - "Invalid or unknown abi {:?} for function {:?} ({:?})", - unknown_abi, canonical_name, self + "Invalid or unknown abi {unknown_abi:?} for function {canonical_name:?} ({self:?})" ); } Ok(abi) => abi, @@ -4532,37 +4665,47 @@ impl CodeGenerator for Function { // suffix. let times_seen = result.overload_number(&canonical_name); if times_seen > 0 { - write!(&mut canonical_name, "{}", times_seen).unwrap(); + write!(&mut canonical_name, "{times_seen}").unwrap(); } + utils::call_discovered_item_callback(ctx, item, || { + DiscoveredItem::Function { + final_name: canonical_name.clone(), + } + }); - let mut has_link_name_attr = false; - if let Some(link_name) = self.link_name() { - attributes.push(attributes::link_name::(link_name)); - has_link_name_attr = true; - } else { - let link_name = mangled_name.unwrap_or(name); - if !is_dynamic_function && - !utils::names_will_be_identical_after_mangling( - &canonical_name, - link_name, - Some(abi), - ) - { + let link_name_attr = self.link_name().or_else(|| { + let mangled_name = mangled_name.unwrap_or(name); + (!utils::names_will_be_identical_after_mangling( + &canonical_name, + mangled_name, + Some(abi), + )) + .then_some(mangled_name) + }); + + if let Some(link_name) = link_name_attr { + if !is_dynamic_function { attributes.push(attributes::link_name::(link_name)); - has_link_name_attr = true; } } - // Unfortunately this can't piggyback on the `attributes` list because - // the #[link(wasm_import_module)] needs to happen before the `extern - // "C"` block. It doesn't get picked up properly otherwise - let wasm_link_attribute = - ctx.options().wasm_import_module_name.as_ref().map(|name| { - quote! { #[link(wasm_import_module = #name)] } + let mut block_attributes = quote! {}; + for attr in &ctx.options().extern_fn_block_attrs { + let parsed_attr = proc_macro2::TokenStream::from_str(attr).unwrap_or_else( + |err| { + panic!( + "Error parsing extern fn block attribute `{attr}`: {err}" + ) + }, + ); + block_attributes.extend(quote! { + #parsed_attr }); + } - let should_wrap = - is_internal && ctx.options().wrap_static_fns && !has_link_name_attr; + let should_wrap = is_internal && + ctx.options().wrap_static_fns && + link_name_attr.is_none(); if should_wrap { let name = canonical_name.clone() + ctx.wrap_static_fns_suffix(); @@ -4604,9 +4747,16 @@ impl CodeGenerator for Function { let ret = utils::fnsig_return_ty(ctx, signature); let ident = ctx.rust_ident(ident); + + let safety = ctx + .options() + .rust_features + .unsafe_extern_blocks + .then(|| quote!(unsafe)); + let tokens = quote! { - #wasm_link_attribute - extern #abi { + #block_attributes + #safety extern #abi { #(#attributes)* pub fn #ident ( #( #args ),* ) #ret; } @@ -4621,19 +4771,22 @@ impl CodeGenerator for Function { // If we're doing dynamic binding generation, add to the dynamic items. if is_dynamic_function { + let ident_str = ident.to_string(); + let symbol = link_name_attr.unwrap_or(&ident_str); let args_identifiers = utils::fnsig_argument_identifiers(ctx, signature); let ret_ty = utils::fnsig_return_ty(ctx, signature); result.dynamic_items().push_func( - ident, + &ident, + symbol, abi, signature.is_variadic(), ctx.options().dynamic_link_require_all, - args, - args_identifiers, - ret, - ret_ty, - attributes, + &args, + &args_identifiers, + &ret, + &ret_ty, + &attributes, ctx, ); } else { @@ -4649,13 +4802,11 @@ fn unsupported_abi_diagnostic( variadic: bool, location: Option<&crate::clang::SourceLocation>, ctx: &BindgenContext, - error: &error::Error, + error: &Error, ) { warn!( - "Skipping {}function `{}` because the {}", + "Skipping {}function `{fn_name}` because the {error}", if variadic { "variadic " } else { "" }, - fn_name, - error ); #[cfg(feature = "experimental")] @@ -4665,10 +4816,8 @@ fn unsupported_abi_diagnostic( let mut diag = Diagnostic::default(); diag.with_title( format!( - "Skipping {}function `{}` because the {}", + "Skipping {}function `{fn_name}` because the {error}", if variadic { "variadic " } else { "" }, - fn_name, - error ), Level::Warning, ) @@ -4698,7 +4847,7 @@ fn unsupported_abi_diagnostic( } } - diag.display() + diag.display(); } } @@ -4708,8 +4857,7 @@ fn variadic_fn_diagnostic( _ctx: &BindgenContext, ) { warn!( - "Cannot generate wrapper for the static variadic function `{}`.", - fn_name, + "Cannot generate wrapper for the static variadic function `{fn_name}`." ); #[cfg(feature = "experimental")] @@ -4718,7 +4866,7 @@ fn variadic_fn_diagnostic( let mut diag = Diagnostic::default(); - diag.with_title(format!("Cannot generate wrapper for the static function `{}`.", fn_name), Level::Warning) + diag.with_title(format!("Cannot generate wrapper for the static function `{fn_name}`."), Level::Warning) .add_annotation("The `--wrap-static-fns` feature does not support variadic functions.", Level::Note) .add_annotation("No code will be generated for this function.", Level::Note); @@ -4736,7 +4884,7 @@ fn variadic_fn_diagnostic( } } - diag.display() + diag.display(); } } @@ -4751,7 +4899,7 @@ fn objc_method_codegen( // This would ideally resolve the method into an Item, and use // Item::process_before_codegen; however, ObjC methods are not currently // made into function items. - let name = format!("{}::{}{}", rust_class_name, prefix, method.rust_name()); + let name = format!("{rust_class_name}::{prefix}{}", method.rust_name()); if ctx.options().blocklisted_items.matches(name) { return; } @@ -4788,8 +4936,7 @@ fn objc_method_codegen( ctx.wrap_unsafe_ops(body) }; - let method_name = - ctx.rust_ident(format!("{}{}", prefix, method.rust_name())); + let method_name = ctx.rust_ident(format!("{prefix}{}", method.rust_name())); methods.push(quote! { unsafe fn #method_name #sig where ::Target: objc::Message + Sized { @@ -4890,7 +5037,7 @@ impl CodeGenerator for ObjCInterface { }; result.push(struct_block); let mut protocol_set: HashSet = Default::default(); - for protocol_id in self.conforms_to.iter() { + for protocol_id in &self.conforms_to { protocol_set.insert(*protocol_id); let protocol_name = ctx.rust_ident( ctx.resolve_type(protocol_id.expect_type_id(ctx)) @@ -4912,9 +5059,8 @@ impl CodeGenerator for ObjCInterface { .expect_type() .kind(); - let parent = match parent { - TypeKind::ObjCInterface(ref parent) => parent, - _ => break, + let TypeKind::ObjCInterface(parent) = parent else { + break; }; parent_class = parent.parent_class; @@ -4935,7 +5081,7 @@ impl CodeGenerator for ObjCInterface { } }; result.push(impl_trait); - for protocol_id in parent.conforms_to.iter() { + for protocol_id in &parent.conforms_to { if protocol_set.insert(*protocol_id) { let protocol_name = ctx.rust_ident( ctx.resolve_type(protocol_id.expect_type_id(ctx)) @@ -4962,8 +5108,7 @@ impl CodeGenerator for ObjCInterface { result.push(from_block); let error_msg = format!( - "This {} cannot be downcasted to {}", - parent_struct_name, child_struct_name + "This {parent_struct_name} cannot be downcasted to {child_struct_name}" ); let try_into_block = quote! { impl std::convert::TryFrom<#parent_struct> for #class_name { @@ -5022,7 +5167,7 @@ pub(crate) fn codegen( let codegen_items = context.codegen_items(); for (id, item) in context.items() { if codegen_items.contains(&id) { - println!("ir: {:?} = {:#?}", id, item); + println!("ir: {id:?} = {item:#?}"); } } } @@ -5030,10 +5175,9 @@ pub(crate) fn codegen( if let Some(path) = context.options().emit_ir_graphviz.as_ref() { match dot::write_dot_file(context, path) { Ok(()) => info!( - "Your dot file was generated successfully into: {}", - path + "Your dot file was generated successfully into: {path}" ), - Err(e) => warn!("{}", e), + Err(e) => warn!("{e}"), } } @@ -5043,7 +5187,7 @@ pub(crate) fn codegen( "Your depfile was generated successfully into: {}", spec.depfile_path.display() ), - Err(e) => warn!("{}", e), + Err(e) => warn!("{e}"), } } @@ -5056,7 +5200,7 @@ pub(crate) fn codegen( if let Some(ref lib_name) = context.options().dynamic_library_name { let lib_ident = context.rust_ident(lib_name); let dynamic_items_tokens = - result.dynamic_items().get_tokens(lib_ident, context); + result.dynamic_items().get_tokens(&lib_ident, context); result.push(dynamic_items_tokens); } @@ -5073,6 +5217,7 @@ pub(crate) mod utils { use super::helpers::BITFIELD_UNIT; use super::serialize::CSerialize; use super::{error, CodegenError, CodegenResult, ToRustTyOrOpaque}; + use crate::callbacks::DiscoveredItemId; use crate::ir::context::BindgenContext; use crate::ir::context::TypeId; use crate::ir::function::{Abi, ClangAbi, FunctionSig}; @@ -5093,14 +5238,10 @@ pub(crate) mod utils { return Ok(()); } - let path = context - .options() - .wrap_static_fns_path - .as_ref() - .map(PathBuf::from) - .unwrap_or_else(|| { - std::env::temp_dir().join("bindgen").join("extern") - }); + let path = context.options().wrap_static_fns_path.as_ref().map_or_else( + || std::env::temp_dir().join("bindgen").join("extern"), + PathBuf::from, + ); let dir = path.parent().unwrap(); @@ -5121,7 +5262,7 @@ pub(crate) mod utils { if !context.options().input_headers.is_empty() { for header in &context.options().input_headers { - writeln!(code, "#include \"{}\"", header)?; + writeln!(code, "#include \"{header}\"")?; } writeln!(code)?; @@ -5129,7 +5270,7 @@ pub(crate) mod utils { if !context.options().input_header_contents.is_empty() { for (name, contents) in &context.options().input_header_contents { - writeln!(code, "// {}\n{}", name, contents)?; + writeln!(code, "// {name}\n{contents}")?; } writeln!(code)?; @@ -5169,10 +5310,10 @@ pub(crate) mod utils { } match ty.kind() { TypeKind::Alias(type_id_alias) => { - type_id = *type_id_alias + type_id = *type_id_alias; } TypeKind::ResolvedTypeRef(type_id_typedef) => { - type_id = *type_id_typedef + type_id = *type_id_typedef; } _ => break, } @@ -5214,7 +5355,7 @@ pub(crate) mod utils { } let bitfield_unit_src = include_str!("./bitfield_unit.rs"); - let bitfield_unit_src = if ctx.options().rust_features().min_const_fn { + let bitfield_unit_src = if true { Cow::Borrowed(bitfield_unit_src) } else { Cow::Owned(bitfield_unit_src.replace("const fn ", "fn ")) @@ -5280,7 +5421,7 @@ pub(crate) mod utils { // If the target supports `const fn`, declare eligible functions // as `const fn` else just `fn`. - let const_fn = if ctx.options().rust_features().min_const_fn { + let const_fn = if true { quote! { const fn } } else { quote! { fn } @@ -5392,7 +5533,7 @@ pub(crate) mod utils { // If the target supports `const fn`, declare eligible functions // as `const fn` else just `fn`. - let const_fn = if ctx.options().rust_features().min_const_fn { + let const_fn = if true { quote! { const fn } } else { quote! { fn } @@ -5491,6 +5632,39 @@ pub(crate) mod utils { result.extend(old_items); } + pub(crate) fn prepend_opaque_array_types( + ctx: &BindgenContext, + result: &mut Vec, + ) { + let mut tys = vec![]; + // If Bindgen could only determine the size and alignment of a type, it is represented like + // this. + for align in ctx.opaque_array_types_needed() { + let ident = if align == 1 { + format_ident!("__BindgenOpaqueArray") + } else { + format_ident!("__BindgenOpaqueArray{align}") + }; + let repr = if align <= 1 { + quote! { #[repr(C)] } + } else { + let explicit = super::helpers::ast_ty::int_expr(align as i64); + quote! { #[repr(C, align(#explicit))] } + }; + tys.push(quote! { + #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)] + #repr + pub struct #ident(pub T); + impl Default for #ident<[T; N]> { + fn default() -> Self { + Self([::default(); N]) + } + } + }); + } + result.splice(0..0, tys); + } + pub(crate) fn build_path( item: &Item, ctx: &BindgenContext, @@ -5576,7 +5750,7 @@ pub(crate) mod utils { pub(crate) fn fnsig_argument_type( ctx: &BindgenContext, - ty: &TypeId, + ty: TypeId, ) -> syn::Type { use super::ToPtr; @@ -5619,7 +5793,7 @@ pub(crate) mod utils { pub(crate) fn fnsig_arguments_iter< 'a, - I: Iterator, crate::ir::context::TypeId)>, + I: Iterator, TypeId)>, >( ctx: &BindgenContext, args_iter: I, @@ -5628,14 +5802,13 @@ pub(crate) mod utils { let mut unnamed_arguments = 0; let mut args = args_iter .map(|(name, ty)| { - let arg_ty = fnsig_argument_type(ctx, ty); + let arg_ty = fnsig_argument_type(ctx, *ty); - let arg_name = match *name { - Some(ref name) => ctx.rust_mangle(name).into_owned(), - None => { - unnamed_arguments += 1; - format!("arg{}", unnamed_arguments) - } + let arg_name = if let Some(ref name) = *name { + ctx.rust_mangle(name).into_owned() + } else { + unnamed_arguments += 1; + format!("arg{unnamed_arguments}") }; assert!(!arg_name.is_empty()); @@ -5648,7 +5821,7 @@ pub(crate) mod utils { .collect::>(); if is_variadic { - args.push(quote! { ... }) + args.push(quote! { ... }); } args @@ -5674,12 +5847,11 @@ pub(crate) mod utils { .argument_types() .iter() .map(|&(ref name, _ty)| { - let arg_name = match *name { - Some(ref name) => ctx.rust_mangle(name).into_owned(), - None => { - unnamed_arguments += 1; - format!("arg{}", unnamed_arguments) - } + let arg_name = if let Some(ref name) = *name { + ctx.rust_mangle(name).into_owned() + } else { + unnamed_arguments += 1; + format!("arg{unnamed_arguments}") }; assert!(!arg_name.is_empty()); @@ -5729,7 +5901,7 @@ pub(crate) mod utils { let mangled_name = mangled_name.as_bytes(); let (mangling_prefix, expect_suffix) = match call_conv { - Some(ClangAbi::Known(Abi::C)) | + Some(ClangAbi::Known(Abi::C | Abi::CUnwind)) | // None is the case for global variables None => { (b'_', false) @@ -5756,7 +5928,7 @@ pub(crate) mod utils { // Check that the mangled name contains the canonical name after the // prefix - if &mangled_name[1..canonical_name.len() + 1] != canonical_name { + if &mangled_name[1..=canonical_name.len()] != canonical_name { return false; } @@ -5784,4 +5956,28 @@ pub(crate) mod utils { true } + + pub(super) fn call_discovered_item_callback( + ctx: &BindgenContext, + item: &Item, + discovered_item_creator: impl Fn() -> crate::callbacks::DiscoveredItem, + ) { + let source_location = item.location().map(|clang_location| { + let (file, line, col, byte_offset) = clang_location.location(); + let file_name = file.name(); + crate::callbacks::SourceLocation { + line, + col, + byte_offset, + file_name, + } + }); + ctx.options().for_each_callback(|cb| { + cb.new_item_found( + DiscoveredItemId::new(item.id().as_usize()), + discovered_item_creator(), + source_location.as_ref(), + ); + }); + } } diff --git a/bindgen/codegen/postprocessing/merge_extern_blocks.rs b/bindgen/codegen/postprocessing/merge_extern_blocks.rs index 10fa0ec80b..e0f6a34baa 100644 --- a/bindgen/codegen/postprocessing/merge_extern_blocks.rs +++ b/bindgen/codegen/postprocessing/merge_extern_blocks.rs @@ -4,7 +4,7 @@ use syn::{ }; pub(super) fn merge_extern_blocks(file: &mut File) { - Visitor.visit_file_mut(file) + Visitor.visit_file_mut(file); } struct Visitor; @@ -12,14 +12,14 @@ struct Visitor; impl VisitMut for Visitor { fn visit_file_mut(&mut self, file: &mut File) { visit_items(&mut file.items); - visit_file_mut(self, file) + visit_file_mut(self, file); } fn visit_item_mod_mut(&mut self, item_mod: &mut ItemMod) { if let Some((_, ref mut items)) = item_mod.content { visit_items(items); } - visit_item_mod_mut(self, item_mod) + visit_item_mod_mut(self, item_mod); } } diff --git a/bindgen/codegen/postprocessing/sort_semantically.rs b/bindgen/codegen/postprocessing/sort_semantically.rs index be94ce69c5..e9bb5dc308 100644 --- a/bindgen/codegen/postprocessing/sort_semantically.rs +++ b/bindgen/codegen/postprocessing/sort_semantically.rs @@ -4,7 +4,7 @@ use syn::{ }; pub(super) fn sort_semantically(file: &mut File) { - Visitor.visit_file_mut(file) + Visitor.visit_file_mut(file); } struct Visitor; @@ -12,14 +12,14 @@ struct Visitor; impl VisitMut for Visitor { fn visit_file_mut(&mut self, file: &mut File) { visit_items(&mut file.items); - visit_file_mut(self, file) + visit_file_mut(self, file); } fn visit_item_mod_mut(&mut self, item_mod: &mut ItemMod) { if let Some((_, ref mut items)) = item_mod.content { visit_items(items); } - visit_item_mod_mut(self, item_mod) + visit_item_mod_mut(self, item_mod); } } diff --git a/bindgen/codegen/serialize.rs b/bindgen/codegen/serialize.rs index 7f00f809f4..9af48aa8ff 100644 --- a/bindgen/codegen/serialize.rs +++ b/bindgen/codegen/serialize.rs @@ -14,8 +14,7 @@ use super::{CodegenError, WrapAsVariadic}; fn get_loc(item: &Item) -> String { item.location() - .map(|x| x.to_string()) - .unwrap_or_else(|| "unknown".to_owned()) + .map_or_else(|| "unknown".to_owned(), |x| x.to_string()) } pub(super) trait CSerialize<'a> { @@ -45,7 +44,7 @@ impl<'a> CSerialize<'a> for Item { func.serialize(ctx, (self, extra), stack, writer) } kind => Err(CodegenError::Serialize { - msg: format!("Cannot serialize item kind {:?}", kind), + msg: format!("Cannot serialize item kind {kind:?}"), loc: get_loc(self), }), } @@ -72,9 +71,10 @@ impl<'a> CSerialize<'a> for Function { }); } - let signature = match ctx.resolve_type(self.signature()).kind() { - TypeKind::Function(signature) => signature, - _ => unreachable!(), + let TypeKind::Function(signature) = + ctx.resolve_type(self.signature()).kind() + else { + unreachable!() }; assert!(!signature.is_variadic()); @@ -102,7 +102,7 @@ impl<'a> CSerialize<'a> for Function { } else { Some(( opt_name.unwrap_or_else(|| { - let name = format!("arg_{}", count); + let name = format!("arg_{count}"); count += 1; name }), @@ -114,7 +114,7 @@ impl<'a> CSerialize<'a> for Function { }; // The name used for the wrapper self. - let wrap_name = format!("{}{}", name, ctx.wrap_static_fns_suffix()); + let wrap_name = format!("{name}{}", ctx.wrap_static_fns_suffix()); // The function's return type let (ret_item, ret_ty) = { @@ -131,15 +131,15 @@ impl<'a> CSerialize<'a> for Function { const INDENT: &str = " "; // Write `wrap_name(args`. - write!(writer, " {}(", wrap_name)?; + write!(writer, " {wrap_name}(")?; serialize_args(&args, ctx, writer)?; if wrap_as_variadic.is_none() { // Write `) { name(` if the function returns void and `) { return name(` if it does not. if ret_ty.is_void() { - write!(writer, ") {{ {}(", name)?; + write!(writer, ") {{ {name}(")?; } else { - write!(writer, ") {{ return {}(", name)?; + write!(writer, ") {{ return {name}(")?; } } else { // Write `, ...) {` @@ -165,7 +165,7 @@ impl<'a> CSerialize<'a> for Function { if !ret_ty.is_void() { write!(writer, "ret = ")?; } - write!(writer, "{}(", name)?; + write!(writer, "{name}(")?; } // Get the arguments names and insert at the right place if necessary `ap` @@ -179,7 +179,7 @@ impl<'a> CSerialize<'a> for Function { // Write `arg_names);`. serialize_sep(", ", args.iter(), ctx, writer, |name, _, buf| { - write!(buf, "{}", name).map_err(From::from) + write!(buf, "{name}").map_err(From::from) })?; #[rustfmt::skip] write!(writer, ");{}", if wrap_as_variadic.is_none() { " " } else { "\n" })?; @@ -198,7 +198,7 @@ impl<'a> CSerialize<'a> for Function { } } -impl<'a> CSerialize<'a> for TypeId { +impl CSerialize<'_> for TypeId { type Extra = (); fn serialize( @@ -228,13 +228,13 @@ impl<'a> CSerialize<'a> for Type { if self.is_const() { write!(writer, "const ")?; } - write!(writer, "void")? + write!(writer, "void")?; } TypeKind::NullPtr => { if self.is_const() { write!(writer, "const ")?; } - write!(writer, "nullptr_t")? + write!(writer, "nullptr_t")?; } TypeKind::Int(int_kind) => { if self.is_const() { @@ -257,8 +257,7 @@ impl<'a> CSerialize<'a> for Type { int_kind => { return Err(CodegenError::Serialize { msg: format!( - "Cannot serialize integer kind {:?}", - int_kind + "Cannot serialize integer kind {int_kind:?}" ), loc: get_loc(item), }) @@ -286,7 +285,7 @@ impl<'a> CSerialize<'a> for Type { FloatKind::Float => write!(writer, "float complex")?, FloatKind::Double => write!(writer, "double complex")?, FloatKind::LongDouble => { - write!(writer, "long double complex")? + write!(writer, "long double complex")?; } FloatKind::Float128 => write!(writer, "__complex128")?, } @@ -294,9 +293,9 @@ impl<'a> CSerialize<'a> for Type { TypeKind::Alias(type_id) => { if let Some(name) = self.name() { if self.is_const() { - write!(writer, "const {}", name)?; + write!(writer, "const {name}")?; } else { - write!(writer, "{}", name)?; + write!(writer, "{name}")?; } } else { type_id.serialize(ctx, (), stack, writer)?; @@ -304,7 +303,7 @@ impl<'a> CSerialize<'a> for Type { } TypeKind::Array(type_id, length) => { type_id.serialize(ctx, (), stack, writer)?; - write!(writer, " [{}]", length)? + write!(writer, " [{length}]")?; } TypeKind::Function(signature) => { if self.is_const() { @@ -320,7 +319,7 @@ impl<'a> CSerialize<'a> for Type { write!(writer, " (")?; while let Some(item) = stack.pop() { - write!(writer, "{}", item)?; + write!(writer, "{item}")?; } write!(writer, ")")?; @@ -342,14 +341,14 @@ impl<'a> CSerialize<'a> for Type { type_id.serialize(ctx, (), &mut stack, buf) }, )?; - write!(writer, ")")? + write!(writer, ")")?; } } TypeKind::ResolvedTypeRef(type_id) => { if self.is_const() { write!(writer, "const ")?; } - type_id.serialize(ctx, (), stack, writer)? + type_id.serialize(ctx, (), stack, writer)?; } TypeKind::Pointer(type_id) => { if self.is_const() { @@ -357,7 +356,7 @@ impl<'a> CSerialize<'a> for Type { } else { stack.push("*".to_owned()); } - type_id.serialize(ctx, (), stack, writer)? + type_id.serialize(ctx, (), stack, writer)?; } TypeKind::Comp(comp_info) => { if self.is_const() { @@ -367,9 +366,9 @@ impl<'a> CSerialize<'a> for Type { let name = item.canonical_name(ctx); match comp_info.kind() { - CompKind::Struct => write!(writer, "struct {}", name)?, - CompKind::Union => write!(writer, "union {}", name)?, - }; + CompKind::Struct => write!(writer, "struct {name}")?, + CompKind::Union => write!(writer, "union {name}")?, + } } TypeKind::Enum(_enum_ty) => { if self.is_const() { @@ -377,20 +376,20 @@ impl<'a> CSerialize<'a> for Type { } let name = item.canonical_name(ctx); - write!(writer, "enum {}", name)?; + write!(writer, "enum {name}")?; } ty => { return Err(CodegenError::Serialize { - msg: format!("Cannot serialize type kind {:?}", ty), + msg: format!("Cannot serialize type kind {ty:?}"), loc: get_loc(item), }) } - }; + } if !stack.is_empty() { write!(writer, " ")?; while let Some(item) = stack.pop() { - write!(writer, "{}", item)?; + write!(writer, "{item}")?; } } diff --git a/bindgen/codegen/struct_layout.rs b/bindgen/codegen/struct_layout.rs index 507c8d40e2..3dfd076c25 100644 --- a/bindgen/codegen/struct_layout.rs +++ b/bindgen/codegen/struct_layout.rs @@ -45,23 +45,6 @@ pub(crate) fn align_to(size: usize, align: usize) -> usize { size + align - rem } -/// Returns the lower power of two byte count that can hold at most n bits. -pub(crate) fn bytes_from_bits_pow2(mut n: usize) -> usize { - if n == 0 { - return 0; - } - - if n <= 8 { - return 1; - } - - if !n.is_power_of_two() { - n = n.next_power_of_two(); - } - - n / 8 -} - #[test] fn test_align_to() { assert_eq!(align_to(1, 1), 1); @@ -71,20 +54,6 @@ fn test_align_to() { assert_eq!(align_to(17, 4), 20); } -#[test] -fn test_bytes_from_bits_pow2() { - assert_eq!(bytes_from_bits_pow2(0), 0); - for i in 1..9 { - assert_eq!(bytes_from_bits_pow2(i), 1); - } - for i in 9..17 { - assert_eq!(bytes_from_bits_pow2(i), 2); - } - for i in 17..33 { - assert_eq!(bytes_from_bits_pow2(i), 4); - } -} - impl<'a> StructLayoutTracker<'a> { pub(crate) fn new( ctx: &'a BindgenContext, @@ -148,7 +117,7 @@ impl<'a> StructLayoutTracker<'a> { } pub(crate) fn saw_bitfield_unit(&mut self, layout: Layout) { - debug!("saw bitfield unit for {}: {:?}", self.name, layout); + debug!("saw bitfield unit for {}: {layout:?}", self.name); self.align_to_latest_field(layout); @@ -248,12 +217,9 @@ impl<'a> StructLayoutTracker<'a> { ); debug!( - "align field {} to {}/{} with {} padding bytes {:?}", - field_name, + "align field {field_name} to {}/{} with {padding_bytes} padding bytes {field_layout:?}", self.latest_offset, field_offset.unwrap_or(0) / 8, - padding_bytes, - field_layout ); let padding_align = if force_padding { @@ -269,15 +235,19 @@ impl<'a> StructLayoutTracker<'a> { } }; - self.latest_offset += field_layout.size; + if is_union { + self.latest_offset = + cmp::max(self.latest_offset, field_layout.size); + } else { + self.latest_offset += field_layout.size; + } self.latest_field_layout = Some(field_layout); self.max_field_align = cmp::max(self.max_field_align, field_layout.align); self.last_field_was_bitfield = false; debug!( - "Offset: {}: {} -> {}", - field_name, + "Offset: {field_name}: {} -> {}", self.latest_offset - field_layout.size, self.latest_offset ); @@ -312,8 +282,7 @@ impl<'a> StructLayoutTracker<'a> { } trace!( - "need a tail padding field for {}: offset {} -> size {}", - comp_name, + "need a tail padding field for {comp_name}: offset {} -> size {}", self.latest_offset, comp_layout.size ); @@ -325,10 +294,7 @@ impl<'a> StructLayoutTracker<'a> { &mut self, layout: Layout, ) -> Option { - debug!( - "pad_struct:\n\tself = {:#?}\n\tlayout = {:#?}", - self, layout - ); + debug!("pad_struct:\n\tself = {self:#?}\n\tlayout = {layout:#?}"); if layout.size < self.latest_offset { warn!( @@ -344,7 +310,7 @@ impl<'a> StructLayoutTracker<'a> { return None; } - let repr_align = self.ctx.options().rust_features().repr_align; + let repr_align = true; // We always pad to get to the correct size if the struct is one of // those we can't align properly. @@ -368,7 +334,7 @@ impl<'a> StructLayoutTracker<'a> { Layout::new(padding_bytes, layout.align) }; - debug!("pad bytes to struct {}, {:?}", self.name, layout); + debug!("pad bytes to struct {}, {layout:?}", self.name); Some(self.padding_field(layout)) } else { @@ -377,7 +343,7 @@ impl<'a> StructLayoutTracker<'a> { } pub(crate) fn requires_explicit_align(&self, layout: Layout) -> bool { - let repr_align = self.ctx.options().rust_features().repr_align; + let repr_align = true; // Always force explicit repr(align) for stuff more than 16-byte aligned // to work-around https://github.com/rust-lang/rust/issues/54341. @@ -401,13 +367,13 @@ impl<'a> StructLayoutTracker<'a> { } fn padding_field(&mut self, layout: Layout) -> proc_macro2::TokenStream { - let ty = helpers::blob(self.ctx, layout); + let ty = helpers::blob(self.ctx, layout, false); let padding_count = self.padding_count; self.padding_count += 1; let padding_field_name = Ident::new( - &format!("__bindgen_padding_{}", padding_count), + &format!("__bindgen_padding_{padding_count}"), Span::call_site(), ); @@ -422,23 +388,22 @@ impl<'a> StructLayoutTracker<'a> { /// Returns whether the new field is known to merge with a bitfield. /// - /// This is just to avoid doing the same check also in pad_field. + /// This is just to avoid doing the same check also in `pad_field`. fn align_to_latest_field(&mut self, new_field_layout: Layout) -> bool { if self.is_packed { // Skip to align fields when packed. return false; } - let layout = match self.latest_field_layout { - Some(l) => l, - None => return false, + let Some(layout) = self.latest_field_layout else { + return false; }; // If it was, we may or may not need to align, depending on what the // current field alignment and the bitfield size and alignment are. debug!( - "align_to_bitfield? {}: {:?} {:?}", - self.last_field_was_bitfield, layout, new_field_layout + "align_to_bitfield? {}: {layout:?} {new_field_layout:?}", + self.last_field_was_bitfield, ); // Avoid divide-by-zero errors if align is 0. diff --git a/bindgen/deps.rs b/bindgen/deps.rs index be31f92896..3f95ac1e89 100644 --- a/bindgen/deps.rs +++ b/bindgen/deps.rs @@ -18,7 +18,7 @@ impl DepfileSpec { let mut buf = format!("{}:", escape(&self.output_module)); for file in deps { - buf = format!("{} {}", buf, escape(file)); + buf = format!("{buf} {}", escape(file)); } buf } diff --git a/bindgen/diagnostics.rs b/bindgen/diagnostics.rs index e6f169e260..f22402ac0e 100644 --- a/bindgen/diagnostics.rs +++ b/bindgen/diagnostics.rs @@ -93,10 +93,10 @@ impl<'a> Diagnostic<'a> { let hide_warning = "\r \r"; let string = dl.to_string(); for line in string.lines() { - println!("cargo:warning={}{}", hide_warning, line); + println!("cargo:warning={hide_warning}{line}"); } } else { - eprintln!("{}\n", dl); + eprintln!("{dl}\n"); } } } @@ -126,8 +126,7 @@ impl<'a> Slice<'a> { line: usize, col: usize, ) -> &mut Self { - write!(name, ":{}:{}", line, col) - .expect("Writing to a string cannot fail"); + write!(name, ":{line}:{col}").expect("Writing to a string cannot fail"); self.filename = Some(name); self.line = Some(line); self diff --git a/bindgen/extra_assertions.rs b/bindgen/extra_assertions.rs index fbddad7825..8526fd42d2 100644 --- a/bindgen/extra_assertions.rs +++ b/bindgen/extra_assertions.rs @@ -2,7 +2,7 @@ //! and/or CI when the `__testing_only_extra_assertions` feature is enabled. /// Simple macro that forwards to assert! when using -/// __testing_only_extra_assertions. +/// `__testing_only_extra_assertions`. macro_rules! extra_assert { ( $cond:expr ) => { if cfg!(feature = "__testing_only_extra_assertions") { diff --git a/bindgen/features.rs b/bindgen/features.rs index 990e4513cb..04450bdee5 100644 --- a/bindgen/features.rs +++ b/bindgen/features.rs @@ -4,85 +4,302 @@ #![deny(clippy::missing_docs_in_private_items)] #![allow(deprecated)] -use std::cmp::Ordering; -use std::io; use std::str::FromStr; +use std::{fmt, io}; + +/// Represents the version of the Rust language to target. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(transparent)] +pub struct RustTarget(Version); + +impl RustTarget { + /// Create a new [`RustTarget`] for a stable release of Rust. + pub fn stable(minor: u64, patch: u64) -> Result { + let target = Self(Version::Stable(minor, patch)); + + if target < EARLIEST_STABLE_RUST { + return Err(InvalidRustTarget::TooEarly); + } + + Ok(target) + } + + const fn minor(&self) -> Option { + match self.0 { + Version::Nightly => None, + Version::Stable(minor, _) => Some(minor), + } + } + + const fn is_compatible(&self, other: &Self) -> bool { + match (self.0, other.0) { + (Version::Stable(minor, _), Version::Stable(other_minor, _)) => { + // We ignore the patch version number as they only include backwards compatible bug + // fixes. + minor >= other_minor + } + // Nightly is compatible with everything + (Version::Nightly, _) => true, + // No stable release is compatible with nightly + (Version::Stable { .. }, Version::Nightly) => false, + } + } +} + +impl Default for RustTarget { + fn default() -> Self { + // Bindgen from build script: default to generating bindings compatible + // with the Rust version currently performing this build. + #[cfg(not(feature = "__cli"))] + { + use std::env; + use std::iter; + use std::process::Command; + use std::sync::OnceLock; + + static CURRENT_RUST: OnceLock> = OnceLock::new(); + + if let Some(current_rust) = *CURRENT_RUST.get_or_init(|| { + let is_build_script = + env::var_os("CARGO_CFG_TARGET_ARCH").is_some(); + if !is_build_script { + return None; + } + + let rustc = env::var_os("RUSTC")?; + let rustc_wrapper = env::var_os("RUSTC_WRAPPER") + .filter(|wrapper| !wrapper.is_empty()); + let wrapped_rustc = + rustc_wrapper.iter().chain(iter::once(&rustc)); + + let mut is_clippy_driver = false; + loop { + let mut wrapped_rustc = wrapped_rustc.clone(); + let mut command = + Command::new(wrapped_rustc.next().unwrap()); + command.args(wrapped_rustc); + if is_clippy_driver { + command.arg("--rustc"); + } + command.arg("--version"); + + let output = command.output().ok()?; + let string = String::from_utf8(output.stdout).ok()?; + + // Version string like "rustc 1.100.0-beta.5 (f0e1d2c3b 2026-10-17)" + let last_line = string.lines().last().unwrap_or(&string); + let (program, rest) = last_line.trim().split_once(' ')?; + if program != "rustc" { + if program.starts_with("clippy") && !is_clippy_driver { + is_clippy_driver = true; + continue; + } + return None; + } + + let number = rest.split([' ', '-', '+']).next()?; + break RustTarget::from_str(number).ok(); + } + }) { + return current_rust; + } + } + + // Bindgen from CLI, or cannot determine compiler version: default to + // generating bindings compatible with the latest stable release of Rust + // that Bindgen knows about. + LATEST_STABLE_RUST + } +} + +impl fmt::Display for RustTarget { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.0 { + Version::Stable(minor, patch) => write!(f, "1.{minor}.{patch}"), + Version::Nightly => "nightly".fmt(f), + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +enum Version { + Stable(u64, u64), + Nightly, +} + +#[derive(Debug, PartialEq, Eq, Hash)] +pub enum InvalidRustTarget { + TooEarly, +} + +impl fmt::Display for InvalidRustTarget { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::TooEarly => write!(f, "the earliest Rust version supported by bindgen is {EARLIEST_STABLE_RUST}"), + } + } +} + +/// This macro defines the Rust editions supported by bindgen. +macro_rules! define_rust_editions { + ($($variant:ident($value:literal) => $minor:literal,)*) => { + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] + #[doc = "Represents Rust Edition for the generated bindings"] + pub enum RustEdition { + $( + #[doc = concat!("The ", stringify!($value), " edition of Rust.")] + $variant, + )* + } + + impl FromStr for RustEdition { + type Err = InvalidRustEdition; + + fn from_str(s: &str) -> Result { + match s { + $(stringify!($value) => Ok(Self::$variant),)* + _ => Err(InvalidRustEdition(s.to_owned())), + } + } + } + + impl fmt::Display for RustEdition { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + $(Self::$variant => stringify!($value).fmt(f),)* + } + } + } + + impl RustEdition { + pub(crate) const ALL: [Self; [$($value,)*].len()] = [$(Self::$variant,)*]; + + pub(crate) fn is_available(self, target: RustTarget) -> bool { + let Some(minor) = target.minor() else { + return true; + }; + + match self { + $(Self::$variant => $minor <= minor,)* + } + } + } + } +} + +#[derive(Debug)] +pub struct InvalidRustEdition(String); + +impl fmt::Display for InvalidRustEdition { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "\"{}\" is not a valid Rust edition", self.0) + } +} + +impl std::error::Error for InvalidRustEdition {} + +define_rust_editions! { + Edition2018(2018) => 31, + Edition2021(2021) => 56, + Edition2024(2024) => 85, +} + +impl RustTarget { + /// Returns the latest edition supported by this target. + pub(crate) fn latest_edition(self) -> RustEdition { + RustEdition::ALL + .iter() + .rev() + .find(|edition| edition.is_available(self)) + .copied() + .expect("bindgen should always support at least one edition") + } +} + +impl Default for RustEdition { + fn default() -> Self { + RustTarget::default().latest_edition() + } +} /// This macro defines the [`RustTarget`] and [`RustFeatures`] types. macro_rules! define_rust_targets { ( - Nightly => {$($nightly_feature:ident $(: #$issue:literal)?),* $(,)?} $(,)? + Nightly => {$($nightly_feature:ident $(($nightly_edition:literal))|* $(: #$issue:literal)?),* $(,)?} $(,)? $( - $(#[$attrs:meta])* - $variant:ident($minor:literal) => {$($feature:ident $(: #$pull:literal)?),* $(,)?}, + $variant:ident($minor:literal) => {$($feature:ident $(($edition:literal))|* $(: #$pull:literal)?),* $(,)?}, )* $(,)? ) => { - /// Represents the version of the Rust language to target. - /// - /// To support a beta release, use the corresponding stable release. - /// - /// This enum will have more variants added as necessary. - #[allow(non_camel_case_types)] - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] - pub enum RustTarget { - /// Rust Nightly + + impl RustTarget { + /// The nightly version of Rust, which introduces the following features:" $(#[doc = concat!( "- [`", stringify!($nightly_feature), "`]", "(", $("https://github.com/rust-lang/rust/pull/", stringify!($issue),)* ")", )])* - Nightly, + #[deprecated = "The use of this constant is deprecated, please use `RustTarget::nightly` instead."] + pub const Nightly: Self = Self::nightly(); + + /// The nightly version of Rust, which introduces the following features:" + $(#[doc = concat!( + "- [`", stringify!($nightly_feature), "`]", + "(", $("https://github.com/rust-lang/rust/pull/", stringify!($issue),)* ")", + )])* + pub const fn nightly() -> Self { + Self(Version::Nightly) + } + $( - #[doc = concat!("Rust 1.", stringify!($minor))] + #[doc = concat!("Version 1.", stringify!($minor), " of Rust, which introduced the following features:")] $(#[doc = concat!( "- [`", stringify!($feature), "`]", "(", $("https://github.com/rust-lang/rust/pull/", stringify!($pull),)* ")", )])* - $(#[$attrs])* - $variant, + #[deprecated = "The use of this constant is deprecated, please use `RustTarget::stable` instead."] + pub const $variant: Self = Self(Version::Stable($minor, 0)); )* - } - - impl RustTarget { - fn minor(self) -> Option { - match self { - $( Self::$variant => Some($minor),)* - Self::Nightly => None - } - } const fn stable_releases() -> [(Self, u64); [$($minor,)*].len()] { [$((Self::$variant, $minor),)*] } } - #[cfg(feature = "__cli")] - /// Strings of allowed `RustTarget` values - pub const RUST_TARGET_STRINGS: &[&str] = &[$(concat!("1.", stringify!($minor)),)*]; - #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub(crate) struct RustFeatures { $($(pub(crate) $feature: bool,)*)* $(pub(crate) $nightly_feature: bool,)* } - impl From for RustFeatures { - fn from(target: RustTarget) -> Self { - if target == RustTarget::Nightly { - return Self { - $($($feature: true,)*)* - $($nightly_feature: true,)* - }; - } - + impl RustFeatures { + /// Compute the features that must be enabled in a specific Rust target with a specific edition. + pub(crate) fn new(target: RustTarget, edition: RustEdition) -> Self { let mut features = Self { $($($feature: false,)*)* $($nightly_feature: false,)* }; - $(if target >= RustTarget::$variant { - $(features.$feature = true;)* - })* + if target.is_compatible(&RustTarget::nightly()) { + $( + let editions: &[RustEdition] = &[$(stringify!($nightly_edition).parse::().ok().expect("invalid edition"),)*]; + + if editions.is_empty() || editions.contains(&edition) { + features.$nightly_feature = true; + } + )* + } + + $( + if target.is_compatible(&RustTarget::$variant) { + $( + let editions: &[RustEdition] = &[$(stringify!($edition).parse::().ok().expect("invalid edition"),)*]; + + if editions.is_empty() || editions.contains(&edition) { + features.$feature = true; + } + )* + } + )* features } @@ -99,43 +316,22 @@ define_rust_targets! { ptr_metadata: #81513, layout_for_ptr: #69835, }, - Stable_1_77(77) => { offset_of: #106655 }, + Stable_1_82(82) => { + unsafe_extern_blocks: #127921, + }, + Stable_1_77(77) => { + offset_of: #106655, + literal_cstr(2021)|(2024): #117472, + }, Stable_1_73(73) => { thiscall_abi: #42202 }, Stable_1_71(71) => { c_unwind_abi: #106075 }, Stable_1_68(68) => { abi_efiapi: #105795 }, Stable_1_64(64) => { core_ffi_c: #94503 }, Stable_1_59(59) => { const_cstr: #54745 }, - Stable_1_47(47) => { larger_arrays: #74060 }, - Stable_1_43(43) => { associated_constants: #68952 }, - Stable_1_40(40) => { non_exhaustive: #44109 }, - Stable_1_36(36) => { maybe_uninit: #60445 }, - Stable_1_33(33) => { repr_packed_n: #57049 }, - #[deprecated] - Stable_1_30(30) => { - core_ffi_c_void: #53910, - min_const_fn: #54835, - }, - #[deprecated] - Stable_1_28(28) => { repr_transparent: #51562 }, - #[deprecated] - Stable_1_27(27) => { must_use_function: #48925 }, - #[deprecated] - Stable_1_26(26) => { i128_and_u128: #49101 }, - #[deprecated] - Stable_1_25(25) => { repr_align: #47006 }, - #[deprecated] - Stable_1_21(21) => { builtin_clone_impls: #43690 }, - #[deprecated] - Stable_1_20(20) => { associated_const: #42809 }, - #[deprecated] - Stable_1_19(19) => { untagged_union: #42068 }, - #[deprecated] - Stable_1_17(17) => { static_lifetime_elision: #39265 }, - #[deprecated] - Stable_1_0(0) => {}, + Stable_1_51(51) => {}, } -/// Latest stable release of Rust +/// Latest stable release of Rust that is supported by bindgen pub const LATEST_STABLE_RUST: RustTarget = { // FIXME: replace all this code by // ``` @@ -143,7 +339,7 @@ pub const LATEST_STABLE_RUST: RustTarget = { // .into_iter() // .max_by_key(|(_, m)| m) // .map(|(t, _)| t) - // .unwrap_or(RustTarget::Nightly) + // .unwrap() // ``` // once those operations can be used in constants. let targets = RustTarget::stable_releases(); @@ -169,66 +365,100 @@ pub const LATEST_STABLE_RUST: RustTarget = { } }; -impl Default for RustTarget { - fn default() -> Self { - LATEST_STABLE_RUST - } -} +/// Earliest stable release of Rust that is supported by bindgen +pub const EARLIEST_STABLE_RUST: RustTarget = { + // FIXME: replace all this code by + // ``` + // RustTarget::stable_releases() + // .into_iter() + // .min_by_key(|(_, m)| m) + // .map(|(t, _)| t) + // .unwrap_or(LATEST_STABLE_RUST) + // ``` + // once those operations can be used in constants. + let targets = RustTarget::stable_releases(); -impl PartialOrd for RustTarget { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} + let mut i = 0; + let mut earliest_target = None; + let Some(mut earliest_minor) = LATEST_STABLE_RUST.minor() else { + unreachable!() + }; + + while i < targets.len() { + let (target, minor) = targets[i]; -impl Ord for RustTarget { - fn cmp(&self, other: &Self) -> Ordering { - match (self.minor(), other.minor()) { - (Some(a), Some(b)) => a.cmp(&b), - (Some(_), None) => Ordering::Less, - (None, Some(_)) => Ordering::Greater, - (None, None) => Ordering::Equal, + if earliest_minor > minor { + earliest_minor = minor; + earliest_target = Some(target); } + + i += 1; } + + match earliest_target { + Some(target) => target, + None => unreachable!(), + } +}; + +fn invalid_input(input: &str, msg: impl fmt::Display) -> io::Error { + io::Error::new( + io::ErrorKind::InvalidInput, + format!("\"{input}\" is not a valid Rust target, {msg}"), + ) } impl FromStr for RustTarget { type Err = io::Error; - fn from_str(s: &str) -> Result { - if s == "nightly" { + fn from_str(input: &str) -> Result { + if input == "nightly" { return Ok(Self::Nightly); } - if let Some(("1", str_minor)) = s.split_once('.') { - if let Ok(minor) = str_minor.parse::() { - for (target, target_minor) in Self::stable_releases() { - if minor == target_minor { - return Ok(target); - } - } - } + let Some((major_str, tail)) = input.split_once('.') else { + return Err(invalid_input(input, "accepted values are of the form \"1.71\", \"1.71.1\" or \"nightly\"." ) ); + }; + + if major_str != "1" { + return Err(invalid_input( + input, + "The largest major version of Rust released is \"1\"", + )); } - Err(io::Error::new( - io::ErrorKind::InvalidInput, - "Got an invalid Rust target. Accepted values are of the form \"1.71\" or \"nightly\"." - )) + let (minor, patch) = if let Some((minor_str, patch_str)) = + tail.split_once('.') + { + let Ok(minor) = minor_str.parse::() else { + return Err(invalid_input(input, "the minor version number must be an unsigned 64-bit integer")); + }; + let Ok(patch) = patch_str.parse::() else { + return Err(invalid_input(input, "the patch version number must be an unsigned 64-bit integer")); + }; + (minor, patch) + } else { + let Ok(minor) = tail.parse::() else { + return Err(invalid_input(input, "the minor version number must be an unsigned 64-bit integer")); + }; + (minor, 0) + }; + + Self::stable(minor, patch).map_err(|err| invalid_input(input, err)) } } -impl std::fmt::Display for RustTarget { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self.minor() { - Some(minor) => write!(f, "1.{}", minor), - None => "nightly".fmt(f), - } +impl RustFeatures { + /// Compute the features that must be enabled in a specific Rust target with the latest edition + /// available in that target. + pub(crate) fn new_with_latest_edition(target: RustTarget) -> Self { + Self::new(target, target.latest_edition()) } } impl Default for RustFeatures { fn default() -> Self { - RustTarget::default().into() + Self::new_with_latest_edition(RustTarget::default()) } } @@ -237,63 +467,96 @@ mod test { use super::*; #[test] - fn target_features() { - let f_1_0 = RustFeatures::from(RustTarget::Stable_1_0); - assert!( - !f_1_0.static_lifetime_elision && - !f_1_0.core_ffi_c_void && - !f_1_0.untagged_union && - !f_1_0.associated_const && - !f_1_0.builtin_clone_impls && - !f_1_0.repr_align && - !f_1_0.thiscall_abi && - !f_1_0.vectorcall_abi + fn release_versions_for_editions() { + assert_eq!( + "1.51".parse::().unwrap().latest_edition(), + RustEdition::Edition2018 ); - let f_1_21 = RustFeatures::from(RustTarget::Stable_1_21); - assert!( - f_1_21.static_lifetime_elision && - !f_1_21.core_ffi_c_void && - f_1_21.untagged_union && - f_1_21.associated_const && - f_1_21.builtin_clone_impls && - !f_1_21.repr_align && - !f_1_21.thiscall_abi && - !f_1_21.vectorcall_abi + assert_eq!( + "1.59".parse::().unwrap().latest_edition(), + RustEdition::Edition2021 + ); + assert_eq!( + "1.85".parse::().unwrap().latest_edition(), + RustEdition::Edition2024 ); - let features = RustFeatures::from(RustTarget::Stable_1_71); + assert_eq!( + "nightly".parse::().unwrap().latest_edition(), + RustEdition::Edition2024 + ); + } + + #[test] + fn target_features() { + let features = + RustFeatures::new_with_latest_edition(RustTarget::Stable_1_71); assert!( features.c_unwind_abi && features.abi_efiapi && !features.thiscall_abi ); - let f_nightly = RustFeatures::from(RustTarget::Nightly); + + let features = RustFeatures::new( + RustTarget::Stable_1_77, + RustEdition::Edition2018, + ); + assert!(!features.literal_cstr); + + let features = + RustFeatures::new_with_latest_edition(RustTarget::Stable_1_77); + assert!(features.literal_cstr); + + let f_nightly = + RustFeatures::new_with_latest_edition(RustTarget::Nightly); assert!( - f_nightly.static_lifetime_elision && - f_nightly.core_ffi_c_void && - f_nightly.untagged_union && - f_nightly.associated_const && - f_nightly.builtin_clone_impls && - f_nightly.maybe_uninit && - f_nightly.repr_align && - f_nightly.thiscall_abi && - f_nightly.vectorcall_abi + f_nightly.vectorcall_abi && + f_nightly.ptr_metadata && + f_nightly.layout_for_ptr + ); + } + + fn test_target(input: &str, expected: RustTarget) { + // Two targets are equivalent if they enable the same set of features + let expected = RustFeatures::new_with_latest_edition(expected); + let found = RustFeatures::new_with_latest_edition( + input.parse::().unwrap(), + ); + assert_eq!( + expected, + found, + "target {input} enables features:\n{found:#?}\nand should enable features:\n{expected:#?}" ); } - fn test_target(target_str: &str, target: RustTarget) { - let target_string = target.to_string(); - assert_eq!(target_str, target_string); - assert_eq!(target, RustTarget::from_str(target_str).unwrap()); + fn test_invalid_target(input: &str) { + assert!( + input.parse::().is_err(), + "{input} should be an invalid target" + ); } #[test] - fn str_to_target() { - test_target("1.0", RustTarget::Stable_1_0); - test_target("1.17", RustTarget::Stable_1_17); - test_target("1.19", RustTarget::Stable_1_19); - test_target("1.21", RustTarget::Stable_1_21); - test_target("1.25", RustTarget::Stable_1_25); + fn valid_targets() { test_target("1.71", RustTarget::Stable_1_71); + test_target("1.71.0", RustTarget::Stable_1_71); + test_target("1.71.1", RustTarget::Stable_1_71); + test_target("1.72", RustTarget::Stable_1_71); + test_target("1.73", RustTarget::Stable_1_73); + test_target("1.18446744073709551615", LATEST_STABLE_RUST); test_target("nightly", RustTarget::Nightly); } + + #[test] + fn invalid_targets() { + test_invalid_target("2.0"); + test_invalid_target("1.cat"); + test_invalid_target("1.0.cat"); + test_invalid_target("1.18446744073709551616"); + test_invalid_target("1.0.18446744073709551616"); + test_invalid_target("1.-1.0"); + test_invalid_target("1.0.-1"); + test_invalid_target("beta"); + test_invalid_target("1.0.0"); + test_invalid_target("1.32.0"); + } } diff --git a/bindgen/ir/analysis/derive.rs b/bindgen/ir/analysis/derive.rs index d8d29ed9a8..7316950ba2 100644 --- a/bindgen/ir/analysis/derive.rs +++ b/bindgen/ir/analysis/derive.rs @@ -104,7 +104,7 @@ fn consider_edge_default(kind: EdgeKind) -> bool { } } -impl<'ctx> CannotDerive<'ctx> { +impl CannotDerive<'_> { fn insert>( &mut self, id: Id, @@ -112,10 +112,8 @@ impl<'ctx> CannotDerive<'ctx> { ) -> ConstrainResult { let id = id.into(); trace!( - "inserting {:?} can_derive<{}>={:?}", - id, + "inserting {id:?} can_derive<{}>={can_derive:?}", self.derive_trait, - can_derive ); if let CanDerive::Yes = can_derive { @@ -168,7 +166,7 @@ impl<'ctx> CannotDerive<'ctx> { return CanDerive::No; } - trace!("ty: {:?}", ty); + trace!("ty: {ty:?}"); if item.is_opaque(self.ctx, &()) { if !self.derive_trait.can_derive_union() && ty.is_union() && @@ -181,26 +179,11 @@ impl<'ctx> CannotDerive<'ctx> { return CanDerive::No; } - let layout_can_derive = - ty.layout(self.ctx).map_or(CanDerive::Yes, |l| { - l.opaque().array_size_within_derive_limit(self.ctx) - }); - - match layout_can_derive { - CanDerive::Yes => { - trace!( - " we can trivially derive {} for the layout", - self.derive_trait - ); - } - _ => { - trace!( - " we cannot derive {} for the layout", - self.derive_trait - ); - } - }; - return layout_can_derive; + trace!( + " we can trivially derive {} for the layout", + self.derive_trait + ); + return CanDerive::Yes; } match *ty.kind() { @@ -217,9 +200,7 @@ impl<'ctx> CannotDerive<'ctx> { TypeKind::Reference(..) | TypeKind::ObjCInterface(..) | TypeKind::ObjCId | - TypeKind::ObjCSel => { - return self.derive_trait.can_derive_simple(ty.kind()); - } + TypeKind::ObjCSel => self.derive_trait.can_derive_simple(ty.kind()), TypeKind::Pointer(inner) => { let inner_type = self.ctx.resolve_type(inner).canonical_type(self.ctx); @@ -236,7 +217,7 @@ impl<'ctx> CannotDerive<'ctx> { // Complex cases need more information TypeKind::Array(t, len) => { let inner_type = - self.can_derive.get(&t.into()).cloned().unwrap_or_default(); + self.can_derive.get(&t.into()).copied().unwrap_or_default(); if inner_type != CanDerive::Yes { trace!( " arrays of T for which we cannot derive {} \ @@ -275,7 +256,7 @@ impl<'ctx> CannotDerive<'ctx> { } TypeKind::Vector(t, len) => { let inner_type = - self.can_derive.get(&t.into()).cloned().unwrap_or_default(); + self.can_derive.get(&t.into()).copied().unwrap_or_default(); if inner_type != CanDerive::Yes { trace!( " vectors of T for which we cannot derive {} \ @@ -342,26 +323,11 @@ impl<'ctx> CannotDerive<'ctx> { return CanDerive::No; } - let layout_can_derive = - ty.layout(self.ctx).map_or(CanDerive::Yes, |l| { - l.opaque() - .array_size_within_derive_limit(self.ctx) - }); - match layout_can_derive { - CanDerive::Yes => { - trace!( - " union layout can trivially derive {}", - self.derive_trait - ); - } - _ => { - trace!( - " union layout cannot derive {}", - self.derive_trait - ); - } - }; - return layout_can_derive; + trace!( + " union layout can trivially derive {}", + self.derive_trait + ); + return CanDerive::Yes; } } @@ -431,13 +397,13 @@ impl<'ctx> CannotDerive<'ctx> { let can_derive = self.can_derive .get(&sub_id) - .cloned() + .copied() .unwrap_or_default(); match can_derive { - CanDerive::Yes => trace!(" member {:?} can derive {}", sub_id, self.derive_trait), - CanDerive::Manually => trace!(" member {:?} cannot derive {}, but it may be implemented", sub_id, self.derive_trait), - CanDerive::No => trace!(" member {:?} cannot derive {}", sub_id, self.derive_trait), + CanDerive::Yes => trace!(" member {sub_id:?} can derive {}", self.derive_trait), + CanDerive::Manually => trace!(" member {sub_id:?} cannot derive {}, but it may be implemented", self.derive_trait), + CanDerive::No => trace!(" member {sub_id:?} cannot derive {}", self.derive_trait), } *candidate.get_or_insert(CanDerive::Yes) |= can_derive; @@ -456,7 +422,7 @@ impl<'ctx> CannotDerive<'ctx> { } impl DeriveTrait { - fn not_by_name(&self, ctx: &BindgenContext, item: &Item) -> bool { + fn not_by_name(self, ctx: &BindgenContext, item: &Item) -> bool { match self { DeriveTrait::Copy => ctx.no_copy_by_name(item), DeriveTrait::Debug => ctx.no_debug_by_name(item), @@ -468,21 +434,21 @@ impl DeriveTrait { } } - fn consider_edge_comp(&self) -> EdgePredicate { + fn consider_edge_comp(self) -> EdgePredicate { match self { DeriveTrait::PartialEqOrPartialOrd => consider_edge_default, _ => |kind| matches!(kind, EdgeKind::BaseMember | EdgeKind::Field), } } - fn consider_edge_typeref(&self) -> EdgePredicate { + fn consider_edge_typeref(self) -> EdgePredicate { match self { DeriveTrait::PartialEqOrPartialOrd => consider_edge_default, _ => |kind| kind == EdgeKind::TypeReference, } } - fn consider_edge_tmpl_inst(&self) -> EdgePredicate { + fn consider_edge_tmpl_inst(self) -> EdgePredicate { match self { DeriveTrait::PartialEqOrPartialOrd => consider_edge_default, _ => |kind| { @@ -494,31 +460,27 @@ impl DeriveTrait { } } - fn can_derive_large_array(&self, ctx: &BindgenContext) -> bool { - if ctx.options().rust_features().larger_arrays { - !matches!(self, DeriveTrait::Default) - } else { - matches!(self, DeriveTrait::Copy) - } + fn can_derive_large_array(self, _: &BindgenContext) -> bool { + !matches!(self, DeriveTrait::Default) } - fn can_derive_union(&self) -> bool { + fn can_derive_union(self) -> bool { matches!(self, DeriveTrait::Copy) } - fn can_derive_compound_with_destructor(&self) -> bool { + fn can_derive_compound_with_destructor(self) -> bool { !matches!(self, DeriveTrait::Copy) } - fn can_derive_compound_with_vtable(&self) -> bool { + fn can_derive_compound_with_vtable(self) -> bool { !matches!(self, DeriveTrait::Default) } - fn can_derive_compound_forward_decl(&self) -> bool { + fn can_derive_compound_forward_decl(self) -> bool { matches!(self, DeriveTrait::Copy | DeriveTrait::Debug) } - fn can_derive_incomplete_array(&self) -> bool { + fn can_derive_incomplete_array(self) -> bool { !matches!( self, DeriveTrait::Copy | @@ -527,63 +489,60 @@ impl DeriveTrait { ) } - fn can_derive_fnptr(&self, f: &FunctionSig) -> CanDerive { + fn can_derive_fnptr(self, f: &FunctionSig) -> CanDerive { match (self, f.function_pointers_can_derive()) { - (DeriveTrait::Copy, _) | (DeriveTrait::Default, _) | (_, true) => { - trace!(" function pointer can derive {}", self); + (DeriveTrait::Copy | DeriveTrait::Default, _) | (_, true) => { + trace!(" function pointer can derive {self}"); CanDerive::Yes } (DeriveTrait::Debug, false) => { - trace!(" function pointer cannot derive {}, but it may be implemented", self); + trace!(" function pointer cannot derive {self}, but it may be implemented"); CanDerive::Manually } (_, false) => { - trace!(" function pointer cannot derive {}", self); + trace!(" function pointer cannot derive {self}"); CanDerive::No } } } - fn can_derive_vector(&self) -> CanDerive { - match self { - DeriveTrait::PartialEqOrPartialOrd => { - // FIXME: vectors always can derive PartialEq, but they should - // not derive PartialOrd: - // https://github.com/rust-lang-nursery/packed_simd/issues/48 - trace!(" vectors cannot derive PartialOrd"); - CanDerive::No - } - _ => { - trace!(" vector can derive {}", self); - CanDerive::Yes - } + fn can_derive_vector(self) -> CanDerive { + if self == DeriveTrait::PartialEqOrPartialOrd { + // FIXME: vectors always can derive PartialEq, but they should + // not derive PartialOrd: + // https://github.com/rust-lang-nursery/packed_simd/issues/48 + trace!(" vectors cannot derive PartialOrd"); + CanDerive::No + } else { + trace!(" vector can derive {self}"); + CanDerive::Yes } } - fn can_derive_pointer(&self) -> CanDerive { - match self { - DeriveTrait::Default => { - trace!(" pointer cannot derive Default"); - CanDerive::No - } - _ => { - trace!(" pointer can derive {}", self); - CanDerive::Yes - } + fn can_derive_pointer(self) -> CanDerive { + if self == DeriveTrait::Default { + trace!(" pointer cannot derive Default"); + CanDerive::No + } else { + trace!(" pointer can derive {self}"); + CanDerive::Yes } } - fn can_derive_simple(&self, kind: &TypeKind) -> CanDerive { + fn can_derive_simple(self, kind: &TypeKind) -> CanDerive { match (self, kind) { // === Default === - (DeriveTrait::Default, TypeKind::Void) | - (DeriveTrait::Default, TypeKind::NullPtr) | - (DeriveTrait::Default, TypeKind::Enum(..)) | - (DeriveTrait::Default, TypeKind::Reference(..)) | - (DeriveTrait::Default, TypeKind::TypeParam) | - (DeriveTrait::Default, TypeKind::ObjCInterface(..)) | - (DeriveTrait::Default, TypeKind::ObjCId) | - (DeriveTrait::Default, TypeKind::ObjCSel) => { + ( + DeriveTrait::Default, + TypeKind::Void | + TypeKind::NullPtr | + TypeKind::Enum(..) | + TypeKind::Reference(..) | + TypeKind::TypeParam | + TypeKind::ObjCInterface(..) | + TypeKind::ObjCId | + TypeKind::ObjCSel, + ) => { trace!(" types that always cannot derive Default"); CanDerive::No } @@ -593,14 +552,16 @@ impl DeriveTrait { ) } // === Hash === - (DeriveTrait::Hash, TypeKind::Float(..)) | - (DeriveTrait::Hash, TypeKind::Complex(..)) => { + ( + DeriveTrait::Hash, + TypeKind::Float(..) | TypeKind::Complex(..), + ) => { trace!(" float cannot derive Hash"); CanDerive::No } // === others === _ => { - trace!(" simple type that can always derive {}", self); + trace!(" simple type that can always derive {self}"); CanDerive::Yes } } @@ -645,7 +606,7 @@ impl<'ctx> MonotoneFramework for CannotDerive<'ctx> { self.ctx .allowlisted_items() .iter() - .cloned() + .copied() .flat_map(|i| { let mut reachable = vec![i]; i.trace( @@ -661,9 +622,9 @@ impl<'ctx> MonotoneFramework for CannotDerive<'ctx> { } fn constrain(&mut self, id: ItemId) -> ConstrainResult { - trace!("constrain: {:?}", id); + trace!("constrain: {id:?}"); - if let Some(CanDerive::No) = self.can_derive.get(&id).cloned() { + if let Some(CanDerive::No) = self.can_derive.get(&id) { trace!(" already know it cannot derive {}", self.derive_trait); return ConstrainResult::Same; } @@ -676,7 +637,7 @@ impl<'ctx> MonotoneFramework for CannotDerive<'ctx> { let is_reached_limit = |l: Layout| l.align > RUST_DERIVE_IN_ARRAY_LIMIT; if !self.derive_trait.can_derive_large_array(self.ctx) && - ty.layout(self.ctx).map_or(false, is_reached_limit) + ty.layout(self.ctx).is_some_and(is_reached_limit) { // We have to be conservative: the struct *could* have enough // padding that we emit an array that is longer than @@ -700,7 +661,7 @@ impl<'ctx> MonotoneFramework for CannotDerive<'ctx> { { if let Some(edges) = self.dependencies.get(&id) { for item in edges { - trace!("enqueue {:?} into worklist", item); + trace!("enqueue {item:?} into worklist"); f(*item); } } @@ -727,6 +688,6 @@ pub(crate) fn as_cannot_derive_set( ) -> HashSet { can_derive .into_iter() - .filter_map(|(k, v)| if v != CanDerive::Yes { Some(k) } else { None }) + .filter_map(|(k, v)| if v == CanDerive::Yes { None } else { Some(k) }) .collect() } diff --git a/bindgen/ir/analysis/has_destructor.rs b/bindgen/ir/analysis/has_destructor.rs index cbcbe55af2..44ef33c21b 100644 --- a/bindgen/ir/analysis/has_destructor.rs +++ b/bindgen/ir/analysis/has_destructor.rs @@ -39,7 +39,7 @@ pub(crate) struct HasDestructorAnalysis<'ctx> { dependencies: HashMap>, } -impl<'ctx> HasDestructorAnalysis<'ctx> { +impl HasDestructorAnalysis<'_> { fn consider_edge(kind: EdgeKind) -> bool { // These are the only edges that can affect whether a type has a // destructor or not. @@ -58,9 +58,8 @@ impl<'ctx> HasDestructorAnalysis<'ctx> { let was_not_already_in_set = self.have_destructor.insert(id); assert!( was_not_already_in_set, - "We shouldn't try and insert {:?} twice because if it was \ - already in the set, `constrain` should have exited early.", - id + "We shouldn't try and insert {id:?} twice because if it was \ + already in the set, `constrain` should have exited early." ); ConstrainResult::Changed } @@ -83,7 +82,7 @@ impl<'ctx> MonotoneFramework for HasDestructorAnalysis<'ctx> { } fn initial_worklist(&self) -> Vec { - self.ctx.allowlisted_items().iter().cloned().collect() + self.ctx.allowlisted_items().iter().copied().collect() } fn constrain(&mut self, id: ItemId) -> ConstrainResult { @@ -94,9 +93,8 @@ impl<'ctx> MonotoneFramework for HasDestructorAnalysis<'ctx> { } let item = self.ctx.resolve_item(id); - let ty = match item.as_type() { - None => return ConstrainResult::Same, - Some(ty) => ty, + let Some(ty) = item.as_type() else { + return ConstrainResult::Same; }; match *ty.kind() { @@ -162,7 +160,7 @@ impl<'ctx> MonotoneFramework for HasDestructorAnalysis<'ctx> { { if let Some(edges) = self.dependencies.get(&id) { for item in edges { - trace!("enqueue {:?} into worklist", item); + trace!("enqueue {item:?} into worklist"); f(*item); } } diff --git a/bindgen/ir/analysis/has_float.rs b/bindgen/ir/analysis/has_float.rs index 219c5a5a8d..e2463ccb96 100644 --- a/bindgen/ir/analysis/has_float.rs +++ b/bindgen/ir/analysis/has_float.rs @@ -39,7 +39,7 @@ pub(crate) struct HasFloat<'ctx> { dependencies: HashMap>, } -impl<'ctx> HasFloat<'ctx> { +impl HasFloat<'_> { fn consider_edge(kind: EdgeKind) -> bool { match kind { EdgeKind::BaseMember | @@ -56,21 +56,20 @@ impl<'ctx> HasFloat<'ctx> { EdgeKind::FunctionParameter | EdgeKind::InnerType | EdgeKind::InnerVar | - EdgeKind::Method => false, + EdgeKind::Method | EdgeKind::Generic => false, } } fn insert>(&mut self, id: Id) -> ConstrainResult { let id = id.into(); - trace!("inserting {:?} into the has_float set", id); + trace!("inserting {id:?} into the has_float set"); let was_not_already_in_set = self.has_float.insert(id); assert!( was_not_already_in_set, - "We shouldn't try and insert {:?} twice because if it was \ - already in the set, `constrain` should have exited early.", - id + "We shouldn't try and insert {id:?} twice because if it was \ + already in the set, `constrain` should have exited early." ); ConstrainResult::Changed @@ -94,11 +93,11 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { } fn initial_worklist(&self) -> Vec { - self.ctx.allowlisted_items().iter().cloned().collect() + self.ctx.allowlisted_items().iter().copied().collect() } fn constrain(&mut self, id: ItemId) -> ConstrainResult { - trace!("constrain: {:?}", id); + trace!("constrain: {id:?}"); if self.has_float.contains(&id) { trace!(" already know it do not have float"); @@ -106,12 +105,9 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { } let item = self.ctx.resolve_item(id); - let ty = match item.as_type() { - Some(ty) => ty, - None => { - trace!(" not a type; ignoring"); - return ConstrainResult::Same; - } + let Some(ty) = item.as_type() else { + trace!(" not a type; ignoring"); + return ConstrainResult::Same; }; match *ty.kind() { @@ -210,7 +206,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { if args_have { trace!( " template args have float, so \ - insantiation also has float" + instantiation also has float" ); return self.insert(id); } @@ -221,7 +217,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { if def_has { trace!( " template definition has float, so \ - insantiation also has" + instantiation also has" ); return self.insert(id); } @@ -238,7 +234,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { { if let Some(edges) = self.dependencies.get(&id) { for item in edges { - trace!("enqueue {:?} into worklist", item); + trace!("enqueue {item:?} into worklist"); f(*item); } } diff --git a/bindgen/ir/analysis/has_type_param_in_array.rs b/bindgen/ir/analysis/has_type_param_in_array.rs index 6665547ca6..687f81560c 100644 --- a/bindgen/ir/analysis/has_type_param_in_array.rs +++ b/bindgen/ir/analysis/has_type_param_in_array.rs @@ -39,7 +39,7 @@ pub(crate) struct HasTypeParameterInArray<'ctx> { dependencies: HashMap>, } -impl<'ctx> HasTypeParameterInArray<'ctx> { +impl HasTypeParameterInArray<'_> { fn consider_edge(kind: EdgeKind) -> bool { match kind { // These are the only edges that can affect whether a type has type parameter @@ -58,25 +58,21 @@ impl<'ctx> HasTypeParameterInArray<'ctx> { EdgeKind::FunctionParameter | EdgeKind::InnerType | EdgeKind::InnerVar | - EdgeKind::Method => false, + EdgeKind::Method | EdgeKind::Generic => false, } } fn insert>(&mut self, id: Id) -> ConstrainResult { let id = id.into(); - trace!( - "inserting {:?} into the has_type_parameter_in_array set", - id - ); + trace!("inserting {id:?} into the has_type_parameter_in_array set"); let was_not_already_in_set = self.has_type_parameter_in_array.insert(id); assert!( was_not_already_in_set, - "We shouldn't try and insert {:?} twice because if it was \ - already in the set, `constrain` should have exited early.", - id + "We shouldn't try and insert {id:?} twice because if it was \ + already in the set, `constrain` should have exited early." ); ConstrainResult::Changed @@ -100,11 +96,11 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { } fn initial_worklist(&self) -> Vec { - self.ctx.allowlisted_items().iter().cloned().collect() + self.ctx.allowlisted_items().iter().copied().collect() } fn constrain(&mut self, id: ItemId) -> ConstrainResult { - trace!("constrain: {:?}", id); + trace!("constrain: {id:?}"); if self.has_type_parameter_in_array.contains(&id) { trace!(" already know it do not have array"); @@ -112,12 +108,9 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { } let item = self.ctx.resolve_item(id); - let ty = match item.as_type() { - Some(ty) => ty, - None => { - trace!(" not a type; ignoring"); - return ConstrainResult::Same; - } + let Some(ty) = item.as_type() else { + trace!(" not a type; ignoring"); + return ConstrainResult::Same; }; match *ty.kind() { @@ -146,17 +139,14 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { TypeKind::Array(t, _) => { let inner_ty = self.ctx.resolve_type(t).canonical_type(self.ctx); - match *inner_ty.kind() { - TypeKind::TypeParam => { - trace!(" Array with Named type has type parameter"); - self.insert(id) - } - _ => { - trace!( - " Array without Named type does have type parameter" - ); - ConstrainResult::Same - } + if let TypeKind::TypeParam = *inner_ty.kind() { + trace!(" Array with Named type has type parameter"); + self.insert(id) + } else { + trace!( + " Array without Named type does have type parameter" + ); + ConstrainResult::Same } } @@ -210,7 +200,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { if args_have { trace!( " template args have array, so \ - insantiation also has array" + instantiation also has array" ); return self.insert(id); } @@ -221,7 +211,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { if def_has { trace!( " template definition has array, so \ - insantiation also has" + instantiation also has" ); return self.insert(id); } @@ -238,7 +228,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { { if let Some(edges) = self.dependencies.get(&id) { for item in edges { - trace!("enqueue {:?} into worklist", item); + trace!("enqueue {item:?} into worklist"); f(*item); } } diff --git a/bindgen/ir/analysis/has_vtable.rs b/bindgen/ir/analysis/has_vtable.rs index 45dea55e6b..b8ecc6088e 100644 --- a/bindgen/ir/analysis/has_vtable.rs +++ b/bindgen/ir/analysis/has_vtable.rs @@ -40,7 +40,7 @@ impl ops::BitOr for HasVtableResult { impl ops::BitOrAssign for HasVtableResult { fn bitor_assign(&mut self, rhs: HasVtableResult) { - *self = self.join(rhs) + *self = self.join(rhs); } } @@ -72,7 +72,7 @@ pub(crate) struct HasVtableAnalysis<'ctx> { dependencies: HashMap>, } -impl<'ctx> HasVtableAnalysis<'ctx> { +impl HasVtableAnalysis<'_> { fn consider_edge(kind: EdgeKind) -> bool { // These are the only edges that can affect whether a type has a // vtable or not. @@ -118,9 +118,9 @@ impl<'ctx> HasVtableAnalysis<'ctx> { let from = from.into(); let to = to.into(); - match self.have_vtable.get(&from).cloned() { + match self.have_vtable.get(&from) { None => ConstrainResult::Same, - Some(r) => self.insert(to, r), + Some(r) => self.insert(to, *r), } } } @@ -142,16 +142,15 @@ impl<'ctx> MonotoneFramework for HasVtableAnalysis<'ctx> { } fn initial_worklist(&self) -> Vec { - self.ctx.allowlisted_items().iter().cloned().collect() + self.ctx.allowlisted_items().iter().copied().collect() } fn constrain(&mut self, id: ItemId) -> ConstrainResult { - trace!("constrain {:?}", id); + trace!("constrain {id:?}"); let item = self.ctx.resolve_item(id); - let ty = match item.as_type() { - None => return ConstrainResult::Same, - Some(ty) => ty, + let Some(ty) = item.as_type() else { + return ConstrainResult::Same; }; // TODO #851: figure out a way to handle deriving from template type parameters. @@ -176,7 +175,7 @@ impl<'ctx> MonotoneFramework for HasVtableAnalysis<'ctx> { } let bases_has_vtable = info.base_members().iter().any(|base| { - trace!(" comp has a base with a vtable: {:?}", base); + trace!(" comp has a base with a vtable: {base:?}"); self.have_vtable.contains_key(&base.ty.into()) }); if bases_has_vtable { @@ -200,7 +199,7 @@ impl<'ctx> MonotoneFramework for HasVtableAnalysis<'ctx> { { if let Some(edges) = self.dependencies.get(&id) { for item in edges { - trace!("enqueue {:?} into worklist", item); + trace!("enqueue {item:?} into worklist"); f(*item); } } @@ -223,7 +222,7 @@ impl<'ctx> From> for HashMap { /// vtable during codegen. /// /// This is not for _computing_ whether the thing has a vtable, it is for -/// looking up the results of the HasVtableAnalysis's computations for a +/// looking up the results of the `HasVtableAnalysis`'s computations for a /// specific thing. pub(crate) trait HasVtable { /// Return `true` if this thing has vtable, `false` otherwise. diff --git a/bindgen/ir/analysis/mod.rs b/bindgen/ir/analysis/mod.rs index 1c05f1216d..74a305edfb 100644 --- a/bindgen/ir/analysis/mod.rs +++ b/bindgen/ir/analysis/mod.rs @@ -280,9 +280,9 @@ mod tests { fn reverse(&self) -> Graph { let mut reversed = Graph::default(); - for (node, edges) in self.0.iter() { + for (node, edges) in &self.0 { reversed.0.entry(*node).or_insert_with(Vec::new); - for referent in edges.iter() { + for referent in edges { reversed .0 .entry(*referent) @@ -306,7 +306,7 @@ mod tests { type Extra = &'a Graph; type Output = HashMap>; - fn new(graph: &'a Graph) -> ReachableFrom { + fn new(graph: &'a Graph) -> Self { let reversed = graph.reverse(); ReachableFrom { reachable: Default::default(), @@ -316,7 +316,7 @@ mod tests { } fn initial_worklist(&self) -> Vec { - self.graph.0.keys().cloned().collect() + self.graph.0.keys().copied().collect() } fn constrain(&mut self, node: Node) -> ConstrainResult { @@ -331,7 +331,7 @@ mod tests { let original_size = self.reachable.entry(node).or_default().len(); - for sub_node in self.graph.0[&node].iter() { + for sub_node in &self.graph.0[&node] { self.reachable.get_mut(&node).unwrap().insert(*sub_node); let sub_reachable = @@ -343,10 +343,10 @@ mod tests { } let new_size = self.reachable[&node].len(); - if original_size != new_size { - ConstrainResult::Changed - } else { + if original_size == new_size { ConstrainResult::Same + } else { + ConstrainResult::Changed } } @@ -354,7 +354,7 @@ mod tests { where F: FnMut(Node), { - for dep in self.reversed.0[&node].iter() { + for dep in &self.reversed.0[&node] { f(*dep); } } @@ -370,13 +370,13 @@ mod tests { fn monotone() { let g = Graph::make_test_graph(); let reachable = analyze::(&g); - println!("reachable = {:#?}", reachable); + println!("reachable = {reachable:#?}"); fn nodes(nodes: A) -> HashSet where A: AsRef<[usize]>, { - nodes.as_ref().iter().cloned().map(Node).collect() + nodes.as_ref().iter().copied().map(Node).collect() } let mut expected = HashMap::default(); @@ -388,7 +388,7 @@ mod tests { expected.insert(Node(6), nodes([8])); expected.insert(Node(7), nodes([3, 4, 5, 6, 7, 8])); expected.insert(Node(8), nodes([])); - println!("expected = {:#?}", expected); + println!("expected = {expected:#?}"); assert_eq!(reachable, expected); } diff --git a/bindgen/ir/analysis/sizedness.rs b/bindgen/ir/analysis/sizedness.rs index edcf47f5c6..ce3c2c3da1 100644 --- a/bindgen/ir/analysis/sizedness.rs +++ b/bindgen/ir/analysis/sizedness.rs @@ -80,7 +80,7 @@ impl ops::BitOr for SizednessResult { impl ops::BitOrAssign for SizednessResult { fn bitor_assign(&mut self, rhs: SizednessResult) { - *self = self.join(rhs) + *self = self.join(rhs); } } @@ -105,7 +105,7 @@ pub(crate) struct SizednessAnalysis<'ctx> { sized: HashMap, } -impl<'ctx> SizednessAnalysis<'ctx> { +impl SizednessAnalysis<'_> { fn consider_edge(kind: EdgeKind) -> bool { // These are the only edges that can affect whether a type is // zero-sized or not. @@ -127,7 +127,7 @@ impl<'ctx> SizednessAnalysis<'ctx> { id: TypeId, result: SizednessResult, ) -> ConstrainResult { - trace!("inserting {:?} for {:?}", result, id); + trace!("inserting {result:?} for {id:?}"); if let SizednessResult::ZeroSized = result { return ConstrainResult::Same; @@ -150,9 +150,9 @@ impl<'ctx> SizednessAnalysis<'ctx> { } fn forward(&mut self, from: TypeId, to: TypeId) -> ConstrainResult { - match self.sized.get(&from).cloned() { + match self.sized.get(&from) { None => ConstrainResult::Same, - Some(r) => self.insert(to, r), + Some(r) => self.insert(to, *r), } } } @@ -191,17 +191,14 @@ impl<'ctx> MonotoneFramework for SizednessAnalysis<'ctx> { self.ctx .allowlisted_items() .iter() - .cloned() .filter_map(|id| id.as_type_id(self.ctx)) .collect() } fn constrain(&mut self, id: TypeId) -> ConstrainResult { - trace!("constrain {:?}", id); + trace!("constrain {id:?}"); - if let Some(SizednessResult::NonZeroSized) = - self.sized.get(&id).cloned() - { + if let Some(SizednessResult::NonZeroSized) = self.sized.get(&id) { trace!(" already know it is not zero-sized"); return ConstrainResult::Same; } @@ -322,7 +319,7 @@ impl<'ctx> MonotoneFramework for SizednessAnalysis<'ctx> { { if let Some(edges) = self.dependencies.get(&id) { for ty in edges { - trace!("enqueue {:?} into worklist", ty); + trace!("enqueue {ty:?} into worklist"); f(*ty); } } diff --git a/bindgen/ir/analysis/template_params.rs b/bindgen/ir/analysis/template_params.rs index a35dcd98e3..df8f861cfe 100644 --- a/bindgen/ir/analysis/template_params.rs +++ b/bindgen/ir/analysis/template_params.rs @@ -161,7 +161,7 @@ pub(crate) struct UsedTemplateParameters<'ctx> { allowlisted_items: HashSet, } -impl<'ctx> UsedTemplateParameters<'ctx> { +impl UsedTemplateParameters<'_> { fn consider_edge(kind: EdgeKind) -> bool { match kind { // For each of these kinds of edges, if the referent uses a template @@ -259,7 +259,6 @@ impl<'ctx> UsedTemplateParameters<'ctx> { a's used template param set should be `Some`", ) .iter() - .cloned() }); used_by_this_id.extend(args); @@ -291,10 +290,8 @@ impl<'ctx> UsedTemplateParameters<'ctx> { for (arg, param) in args.iter().zip(params.iter()) { trace!( - " instantiation's argument {:?} is used if definition's \ - parameter {:?} is used", - arg, - param + " instantiation's argument {arg:?} is used if definition's \ + parameter {param:?} is used", ); if used_by_def.contains(¶m.into()) { @@ -322,8 +319,7 @@ impl<'ctx> UsedTemplateParameters<'ctx> { arg's used template param set should be \ `Some`", ) - .iter() - .cloned(); + .iter(); used_by_this_id.extend(used_by_arg); } } @@ -355,12 +351,10 @@ impl<'ctx> UsedTemplateParameters<'ctx> { sub_id's used template param set should be \ `Some`", ) - .iter() - .cloned(); + .iter(); trace!( - " union with {:?}'s usage: {:?}", - sub_id, + " union with {sub_id:?}'s usage: {:?}", used_by_sub_id.clone().collect::>() ); @@ -380,11 +374,11 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { let mut used = HashMap::default(); let mut dependencies = HashMap::default(); let allowlisted_items: HashSet<_> = - ctx.allowlisted_items().iter().cloned().collect(); + ctx.allowlisted_items().iter().copied().collect(); let allowlisted_and_blocklisted_items: ItemSet = allowlisted_items .iter() - .cloned() + .copied() .flat_map(|i| { let mut reachable = vec![i]; i.trace( @@ -470,7 +464,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { // (This is so that every item we call `constrain` on is guaranteed // to have a set of template parameters, and we can allow // blocklisted templates to use all of their parameters). - for item in allowlisted_items.iter() { + for item in &allowlisted_items { extra_assert!(used.contains_key(item)); extra_assert!(dependencies.contains_key(item)); item.trace( @@ -480,7 +474,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { extra_assert!(dependencies.contains_key(&sub_item)); }, &(), - ) + ); } } @@ -498,7 +492,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { self.ctx .allowlisted_items() .iter() - .cloned() + .copied() .flat_map(|i| { let mut reachable = vec![i]; i.trace( @@ -524,8 +518,8 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { // an analog to slice::split_at_mut. let mut used_by_this_id = self.take_this_id_usage_set(id); - trace!("constrain {:?}", id); - trace!(" initially, used set is {:?}", used_by_this_id); + trace!("constrain {id:?}"); + trace!(" initially, used set is {used_by_this_id:?}"); let original_len = used_by_this_id.len(); @@ -562,7 +556,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { _ => self.constrain_join(&mut used_by_this_id, item), } - trace!(" finally, used set is {:?}", used_by_this_id); + trace!(" finally, used set is {used_by_this_id:?}"); let new_len = used_by_this_id.len(); assert!( @@ -576,10 +570,10 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { self.used.insert(id, Some(used_by_this_id)); extra_assert!(self.used.values().all(|v| v.is_some())); - if new_len != original_len { - ConstrainResult::Changed - } else { + if new_len == original_len { ConstrainResult::Same + } else { + ConstrainResult::Changed } } @@ -589,7 +583,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { { if let Some(edges) = self.dependencies.get(&item) { for item in edges { - trace!("enqueue {:?} into worklist", item); + trace!("enqueue {item:?} into worklist"); f(*item); } } diff --git a/bindgen/ir/annotations.rs b/bindgen/ir/annotations.rs index 12295288c1..7f5d74b3ee 100644 --- a/bindgen/ir/annotations.rs +++ b/bindgen/ir/annotations.rs @@ -28,7 +28,7 @@ impl FromStr for FieldVisibilityKind { "private" => Ok(Self::Private), "crate" => Ok(Self::PublicCrate), "public" => Ok(Self::Public), - _ => Err(format!("Invalid visibility kind: `{}`", s)), + _ => Err(format!("Invalid visibility kind: `{s}`")), } } } @@ -213,7 +213,7 @@ impl Annotations { comment .get_tag_attrs() .next() - .map_or(false, |attr| attr.name == "rustbindgen") + .is_some_and(|attr| attr.name == "rustbindgen") { *matched = true; for attr in comment.get_tag_attrs() { @@ -227,19 +227,19 @@ impl Annotations { "replaces" => { self.use_instead_of = Some( attr.value.split("::").map(Into::into).collect(), - ) + ); } "derive" => self.derives.push(attr.value), "attribute" => self.attributes.push(attr.value), "private" => { - self.visibility_kind = if attr.value != "false" { - Some(FieldVisibilityKind::Private) - } else { + self.visibility_kind = if attr.value == "false" { Some(FieldVisibilityKind::Public) + } else { + Some(FieldVisibilityKind::Private) }; } "accessor" => { - self.accessor_kind = Some(parse_accessor(&attr.value)) + self.accessor_kind = Some(parse_accessor(&attr.value)); } "constant" => self.constify_enum_variant = true, _ => {} diff --git a/bindgen/ir/comment.rs b/bindgen/ir/comment.rs index 7b6f105a4d..a4ba320186 100644 --- a/bindgen/ir/comment.rs +++ b/bindgen/ir/comment.rs @@ -13,7 +13,7 @@ enum Kind { /// Preprocesses a C/C++ comment so that it is a valid Rust comment. pub(crate) fn preprocess(comment: &str) -> String { - match self::kind(comment) { + match kind(comment) { Some(Kind::SingleLines) => preprocess_single_lines(comment), Some(Kind::MultiLine) => preprocess_multi_line(comment), None => comment.to_owned(), @@ -58,7 +58,7 @@ fn preprocess_multi_line(comment: &str) -> String { .collect(); // Remove the trailing line corresponding to the `*/`. - if lines.last().map_or(false, |l| l.trim().is_empty()) { + if lines.last().is_some_and(|l| l.trim().is_empty()) { lines.pop(); } diff --git a/bindgen/ir/comp.rs b/bindgen/ir/comp.rs index 036e7e5c8f..c67f9a2597 100644 --- a/bindgen/ir/comp.rs +++ b/bindgen/ir/comp.rs @@ -12,7 +12,7 @@ use super::template::TemplateParameters; use super::traversal::{EdgeKind, Trace, Tracer}; use super::ty::RUST_DERIVE_IN_ARRAY_LIMIT; use crate::clang; -use crate::codegen::struct_layout::{align_to, bytes_from_bits_pow2}; +use crate::codegen::struct_layout::align_to; use crate::ir::derive::CanDeriveCopy; use crate::parse::ParseError; use crate::HashMap; @@ -56,16 +56,16 @@ pub(crate) enum MethodKind { impl MethodKind { /// Is this a destructor method? - pub(crate) fn is_destructor(&self) -> bool { + pub(crate) fn is_destructor(self) -> bool { matches!( - *self, + self, MethodKind::Destructor | MethodKind::VirtualDestructor { .. } ) } /// Is this a pure virtual method? - pub(crate) fn is_pure_virtual(&self) -> bool { - match *self { + pub(crate) fn is_pure_virtual(self) -> bool { + match self { MethodKind::Virtual { pure_virtual } | MethodKind::VirtualDestructor { pure_virtual } => pure_virtual, _ => false, @@ -361,7 +361,7 @@ impl Bitfield { "`Bitfield::getter_name` called on anonymous field" ); self.getter_name.as_ref().expect( - "`Bitfield::getter_name` should only be called after\ + "`Bitfield::getter_name` should only be called after \ assigning bitfield accessor names", ) } @@ -376,7 +376,7 @@ impl Bitfield { "`Bitfield::setter_name` called on anonymous field" ); self.setter_name.as_ref().expect( - "`Bitfield::setter_name` should only be called\ + "`Bitfield::setter_name` should only be called \ after assigning bitfield accessor names", ) } @@ -560,18 +560,12 @@ where fields: &mut E, bitfield_unit_count: &mut usize, unit_size_in_bits: usize, - unit_align_in_bits: usize, bitfields: Vec, - packed: bool, ) where E: Extend, { *bitfield_unit_count += 1; - let align = if packed { - 1 - } else { - bytes_from_bits_pow2(unit_align_in_bits) - }; + let align = 1; let size = align_to(unit_size_in_bits, 8) / 8; let layout = Layout::new(size, align); fields.extend(Some(Field::Bitfields(BitfieldUnit { @@ -581,70 +575,45 @@ where }))); } + // The offset we're in inside the struct, if we know it (we might not know it in presence of + // templates). + let mut start_offset_in_struct = 0; let mut max_align = 0; - let mut unfilled_bits_in_unit = 0; let mut unit_size_in_bits = 0; - let mut unit_align = 0; let mut bitfields_in_unit = vec![]; - // TODO(emilio): Determine this from attributes or pragma ms_struct - // directives. Also, perhaps we should check if the target is MSVC? - const is_ms_struct: bool = false; - + // TODO(emilio): Deal with ms_struct bitfield layout for MSVC? for bitfield in raw_bitfields { let bitfield_width = bitfield.bitfield_width().unwrap() as usize; let bitfield_layout = ctx.resolve_type(bitfield.ty()).layout(ctx).ok_or(())?; - let bitfield_size = bitfield_layout.size; let bitfield_align = bitfield_layout.align; + let bitfield_size = bitfield_layout.size; - let mut offset = unit_size_in_bits; - if !packed { - if is_ms_struct { - if unit_size_in_bits != 0 && - (bitfield_width == 0 || - bitfield_width > unfilled_bits_in_unit) - { - // We've reached the end of this allocation unit, so flush it - // and its bitfields. - unit_size_in_bits = - align_to(unit_size_in_bits, unit_align * 8); - flush_allocation_unit( - fields, - bitfield_unit_count, - unit_size_in_bits, - unit_align, - mem::take(&mut bitfields_in_unit), - packed, - ); + if unit_size_in_bits == 0 { + start_offset_in_struct = bitfield.offset().unwrap_or(0); + } - // Now we're working on a fresh bitfield allocation unit, so reset - // the current unit size and alignment. - offset = 0; - unit_align = 0; - } - } else if offset != 0 && - (bitfield_width == 0 || - (offset & (bitfield_align * 8 - 1)) + bitfield_width > - bitfield_size * 8) - { - offset = align_to(offset, bitfield_align * 8); - } + let mut offset_in_struct = + bitfield.offset().unwrap_or(unit_size_in_bits); + + // A zero-width field serves as alignment / padding. + if !packed && + offset_in_struct != 0 && + (bitfield_width == 0 || + (offset_in_struct & (bitfield_align * 8 - 1)) + + bitfield_width > + bitfield_size * 8) + { + offset_in_struct = align_to(offset_in_struct, bitfield_align * 8); } - // According to the x86[-64] ABI spec: "Unnamed bit-fields’ types do not - // affect the alignment of a structure or union". This makes sense: such - // bit-fields are only used for padding, and we can't perform an - // un-aligned read of something we can't read because we can't even name - // it. + // According to the x86[-64] ABI spec: "Unnamed bit-fields’ types do not affect the + // alignment of a structure or union". This makes sense: such bit-fields are only used for + // padding, and we can't perform an un-aligned read of something we can't read because we + // can't even name it. if bitfield.name().is_some() { max_align = cmp::max(max_align, bitfield_align); - - // NB: The `bitfield_width` here is completely, absolutely - // intentional. Alignment of the allocation unit is based on the - // maximum bitfield width, not (directly) on the bitfields' types' - // alignment. - unit_align = cmp::max(unit_align, bitfield_width); } // Always keep all bitfields around. While unnamed bitifields are used @@ -652,15 +621,12 @@ where // bitfields over their types size cause weird allocation size behavior from clang. // Therefore, all bitfields needed to be kept around in order to check for this // and make the struct opaque in this case - bitfields_in_unit.push(Bitfield::new(offset, bitfield)); - - unit_size_in_bits = offset + bitfield_width; - - // Compute what the physical unit's final size would be given what we - // have seen so far, and use that to compute how many bits are still - // available in the unit. - let data_size = align_to(unit_size_in_bits, bitfield_align * 8); - unfilled_bits_in_unit = data_size - unit_size_in_bits; + bitfields_in_unit.push(Bitfield::new( + offset_in_struct - start_offset_in_struct, + bitfield, + )); + unit_size_in_bits = + offset_in_struct - start_offset_in_struct + bitfield_width; } if unit_size_in_bits != 0 { @@ -669,9 +635,7 @@ where fields, bitfield_unit_count, unit_size_in_bits, - unit_align, bitfields_in_unit, - packed, ); } @@ -782,7 +746,7 @@ impl CompFields { getter }; let setter = { - let setter = format!("set_{}", bitfield_name); + let setter = format!("set_{bitfield_name}"); let mut setter = ctx.rust_mangle(&setter).to_string(); if has_method(methods, ctx, &setter) { setter.push_str("_bindgen_bitfield"); @@ -803,9 +767,8 @@ impl CompFields { anon_field_counter += 1; *name = Some(format!( - "{}{}", + "{}{anon_field_counter}", ctx.options().anon_fields_prefix, - anon_field_counter )); } Field::Bitfields(ref mut bu) => { @@ -1018,6 +981,7 @@ pub(crate) struct CompInfo { /// The inner types that were declared inside this class, in something like: /// + /// ```c++ /// class Foo { /// typedef int FooTy; /// struct Bar { @@ -1026,6 +990,7 @@ pub(crate) struct CompInfo { /// } /// /// static Foo::Bar const = {3}; + /// ``` inner_types: Vec, /// Set of static constants declared inside this class. @@ -1044,7 +1009,7 @@ pub(crate) struct CompInfo { has_nonempty_base: bool, /// If this type has a template parameter which is not a type (e.g.: a - /// size_t) + /// `size_t`) has_non_type_template_params: bool, /// Whether this type has a bit field member whose width couldn't be @@ -1057,7 +1022,7 @@ pub(crate) struct CompInfo { /// Used to know if we've found an opaque attribute that could cause us to /// generate a type with invalid layout. This is explicitly used to avoid us - /// generating bad alignments when parsing types like max_align_t. + /// generating bad alignments when parsing types like `max_align_t`. /// /// It's not clear what the behavior should be here, if generating the item /// and pray, or behave as an opaque type. @@ -1099,7 +1064,7 @@ impl CompInfo { /// /// If we're a union without known layout, we try to compute it from our /// members. This is not ideal, but clang fails to report the size for these - /// kind of unions, see test/headers/template_union.hpp + /// kind of unions, see `test/headers/template_union.hpp` pub(crate) fn layout(&self, ctx: &BindgenContext) -> Option { // We can't do better than clang here, sorry. if self.kind == CompKind::Struct { @@ -1163,14 +1128,14 @@ impl CompInfo { match self.fields { CompFields::Error => {} CompFields::After { ref fields, .. } => { - for field in fields.iter() { + for field in fields { if let Some(layout) = field.layout(ctx) { callback(layout); } } } CompFields::Before(ref raw_fields) => { - for field in raw_fields.iter() { + for field in raw_fields { let field_ty = ctx.resolve_type(field.0.ty); if let Some(layout) = field_ty.layout(ctx) { callback(layout); @@ -1180,7 +1145,8 @@ impl CompInfo { } } - fn has_bitfields(&self) -> bool { + /// Returns whether we have any bitfield within the struct. + pub(crate) fn has_bitfields(&self) -> bool { match self.fields { CompFields::Error => false, CompFields::After { @@ -1214,7 +1180,7 @@ impl CompInfo { } /// Do we see a virtual function during parsing? - /// Get the has_own_virtual_method boolean. + /// Get the `has_own_virtual_method` boolean. pub(crate) fn has_own_virtual_method(&self) -> bool { self.has_own_virtual_method } @@ -1278,7 +1244,7 @@ impl CompInfo { let kind = kind?; - debug!("CompInfo::from_ty({:?}, {:?})", kind, cursor); + debug!("CompInfo::from_ty({kind:?}, {cursor:?})"); let mut ci = CompInfo::new(kind); ci.is_forward_declaration = @@ -1466,7 +1432,7 @@ impl CompInfo { let field_name = match ci.base_members.len() { 0 => "_base".into(), - n => format!("_base_{}", n), + n => format!("_base_{n}"), }; let type_id = Item::from_ty_or_ref(cur.cur_type(), cur, None, ctx); @@ -1474,8 +1440,7 @@ impl CompInfo { ty: type_id, kind, field_name, - is_pub: cur.access_specifier() == - clang_sys::CX_CXXPublic, + is_pub: cur.access_specifier() == CX_CXXPublic, }); } CXCursor_Constructor | CXCursor_Destructor | @@ -1614,7 +1579,7 @@ impl CompInfo { _ => CompKind::Struct, }, _ => { - warn!("Unknown kind for comp type: {:?}", cursor); + warn!("Unknown kind for comp type: {cursor:?}"); return Err(ParseError::Continue); } }) @@ -1674,7 +1639,7 @@ impl CompInfo { pub(crate) fn already_packed(&self, ctx: &BindgenContext) -> Option { let mut total_size: usize = 0; - for field in self.fields().iter() { + for field in self.fields() { let layout = field.layout(ctx)?; if layout.align != 0 && total_size % layout.align != 0 { @@ -1699,7 +1664,7 @@ impl CompInfo { layout: Option<&Layout>, ) { let packed = self.is_packed(ctx, layout); - self.fields.compute_bitfield_units(ctx, packed) + self.fields.compute_bitfield_units(ctx, packed); } /// Assign for each anonymous field a generated name. @@ -1710,12 +1675,12 @@ impl CompInfo { /// Returns whether the current union can be represented as a Rust `union` /// /// Requirements: - /// 1. Current RustTarget allows for `untagged_union` - /// 2. Each field can derive `Copy` or we use ManuallyDrop. + /// 1. Current `RustTarget` allows for `untagged_union` + /// 2. Each field can derive `Copy` or we use `ManuallyDrop`. /// 3. It's not zero-sized. /// /// Second boolean returns whether all fields can be copied (and thus - /// ManuallyDrop is not needed). + /// `ManuallyDrop` is not needed). pub(crate) fn is_rust_union( &self, ctx: &BindgenContext, @@ -1753,7 +1718,7 @@ impl CompInfo { return (false, false); } - if layout.map_or(false, |l| l.size == 0) { + if layout.is_some_and(|l| l.size == 0) { return (false, false); } @@ -1817,7 +1782,11 @@ impl DotAttributes for CompInfo { impl IsOpaque for CompInfo { type Extra = Option; - fn is_opaque(&self, ctx: &BindgenContext, layout: &Option) -> bool { + fn is_opaque( + &self, + ctx: &BindgenContext, + _layout: &Option, + ) -> bool { if self.has_non_type_template_params || self.has_unevaluable_bit_field_width { @@ -1848,23 +1817,6 @@ impl IsOpaque for CompInfo { return true; } - if !ctx.options().rust_features().repr_packed_n { - // If we don't have `#[repr(packed(N)]`, the best we can - // do is make this struct opaque. - // - // See https://github.com/rust-lang/rust-bindgen/issues/537 and - // https://github.com/rust-lang/rust/issues/33158 - if self.is_packed(ctx, layout.as_ref()) && - layout.map_or(false, |l| l.align > 1) - { - warn!("Found a type that is both packed and aligned to greater than \ - 1; Rust before version 1.33 doesn't have `#[repr(packed(N))]`, so we \ - are treating it as opaque. You may wish to set bindgen's rust target \ - version to 1.33 or later to enable `#[repr(packed(N))]` support."); - return true; - } - } - false } } diff --git a/bindgen/ir/context.rs b/bindgen/ir/context.rs index 75f6a1ec8f..346d2932f7 100644 --- a/bindgen/ir/context.rs +++ b/bindgen/ir/context.rs @@ -29,8 +29,6 @@ use quote::ToTokens; use std::borrow::Cow; use std::cell::{Cell, RefCell}; use std::collections::{BTreeSet, HashMap as StdHashMap}; -use std::fs::OpenOptions; -use std::io::Write; use std::mem; use std::path::Path; @@ -198,8 +196,8 @@ impl From for usize { impl ItemId { /// Get a numeric representation of this ID. - pub(crate) fn as_usize(&self) -> usize { - (*self).into() + pub(crate) fn as_usize(self) -> usize { + self.into() } } @@ -310,7 +308,7 @@ enum TypeKey { /// A context used during parsing and generation of structs. #[derive(Debug)] pub(crate) struct BindgenContext { - /// The map of all the items parsed so far, keyed off ItemId. + /// The map of all the items parsed so far, keyed off `ItemId`. items: Vec>, /// Clang USR to type map. This is needed to be able to associate types with @@ -319,7 +317,7 @@ pub(crate) struct BindgenContext { /// Maps from a cursor to the item ID of the named template type parameter /// for that cursor. - type_params: HashMap, + type_params: HashMap, /// A cursor to module map. Similar reason than above. modules: HashMap, @@ -330,13 +328,13 @@ pub(crate) struct BindgenContext { /// Current module being traversed. current_module: ModuleId, - /// A HashMap keyed on a type definition, and whose value is the parent ID + /// A `HashMap` keyed on a type definition, and whose value is the parent ID /// of the declaration. /// /// This is used to handle the cases where the semantic and the lexical /// parents of the cursor differ, like when a nested class is defined /// outside of the parent class. - semantic_parents: HashMap, + semantic_parents: HashMap, /// A stack with the current type declarations and types we're parsing. This /// is needed to avoid infinite recursion when parsing a type like: @@ -346,7 +344,7 @@ pub(crate) struct BindgenContext { /// This means effectively, that a type has a potential ID before knowing if /// it's a correct type. But that's not important in practice. /// - /// We could also use the `types` HashMap, but my intention with it is that + /// We could also use the `types` `HashMap`, but my intention with it is that /// only valid types and declarations end up there, and this could /// potentially break that assumption. currently_parsed_types: Vec, @@ -355,7 +353,7 @@ pub(crate) struct BindgenContext { /// hard errors while parsing duplicated macros, as well to allow macro /// expression parsing. /// - /// This needs to be an std::HashMap because the cexpr API requires it. + /// This needs to be an `std::HashMap` because the `cexpr` API requires it. parsed_macros: StdHashMap, cexpr::expr::EvalResult>, /// A map with all include locations. @@ -388,6 +386,9 @@ pub(crate) struct BindgenContext { /// The options given by the user via cli or other medium. options: BindgenOptions, + /// Whether an opaque array was generated + generated_opaque_array: RefCell>, + /// Whether a bindgen complex was generated generated_bindgen_complex: Cell, @@ -501,7 +502,7 @@ struct AllowlistedItemsTraversal<'ctx> { traversal: ItemTraversal<'ctx, ItemSet, Vec>, } -impl<'ctx> Iterator for AllowlistedItemsTraversal<'ctx> { +impl Iterator for AllowlistedItemsTraversal<'_> { type Item = ItemId; fn next(&mut self) -> Option { @@ -595,6 +596,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" options, generated_bindgen_complex: Cell::new(false), generated_bindgen_float16: Cell::new(false), + generated_opaque_array: Default::default(), allowlisted: None, blocklisted_types_implement_traits: Default::default(), codegen_items: None, @@ -619,7 +621,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.target_info.triple.starts_with("wasm32-") } - /// Creates a timer for the current bindgen phase. If time_phases is `true`, + /// Creates a timer for the current bindgen phase. If `time_phases` is `true`, /// the timer will print to stderr when it is dropped, otherwise it will do /// nothing. pub(crate) fn timer<'a>(&self, name: &'a str) -> Timer<'a> { @@ -698,10 +700,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" declaration: Option, location: Option, ) { - debug!( - "BindgenContext::add_item({:?}, declaration: {:?}, loc: {:?}", - item, declaration, location - ); + debug!("BindgenContext::add_item({item:?}, declaration: {declaration:?}, loc: {location:?}"); debug_assert!( declaration.is_some() || !item.kind().is_type() || @@ -725,7 +724,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.need_bitfield_allocation.push(id); } - let old_item = mem::replace(&mut self.items[id.0], Some(item)); + let old_item = self.items[id.0].replace(item); assert!( old_item.is_none(), "should not have already associated an item with the given id" @@ -753,8 +752,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" // Fortunately, we don't care about those types being // duplicated, so we can just ignore them. debug!( - "Invalid declaration {:?} found for type {:?}", - declaration, + "Invalid declaration {declaration:?} found for type {:?}", self.resolve_item_fallible(id) .unwrap() .kind() @@ -768,10 +766,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" } else if let Some(usr) = declaration.usr() { TypeKey::Usr(usr) } else { - warn!( - "Valid declaration with no USR: {:?}, {:?}", - declaration, location - ); + warn!("Valid declaration with no USR: {declaration:?}, {location:?}"); TypeKey::Declaration(declaration) }; @@ -785,7 +780,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// codegen'd, even if its parent is not allowlisted. See issue #769 for /// details. fn add_item_to_module(&mut self, item: &Item) { - assert!(item.id() != self.root_module); + assert_ne!(item.id(), self.root_module); assert!(self.resolve_item_fallible(item.id()).is_none()); if let Some(ref mut parent) = self.items[item.parent_id().0] { @@ -807,7 +802,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.current_module ); - self.items[(self.current_module.0).0] + self.items[self.current_module.0 .0] .as_mut() .expect("Should always have an item for self.current_module") .as_module_mut() @@ -817,15 +812,8 @@ If you encounter an error missing from this list, please file an issue or a PR!" } /// Add a new named template type parameter to this context's item set. - pub(crate) fn add_type_param( - &mut self, - item: Item, - definition: clang::Cursor, - ) { - debug!( - "BindgenContext::add_type_param: item = {:?}; definition = {:?}", - item, definition - ); + pub(crate) fn add_type_param(&mut self, item: Item, definition: Cursor) { + debug!("BindgenContext::add_type_param: item = {item:?}; definition = {definition:?}"); assert!( item.expect_type().is_type_param(), @@ -839,7 +827,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.add_item_to_module(&item); let id = item.id(); - let old_item = mem::replace(&mut self.items[id.0], Some(item)); + let old_item = self.items[id.0].replace(item); assert!( old_item.is_none(), "should not have already associated an item with the given id" @@ -856,15 +844,12 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Get the named type defined at the given cursor location, if we've /// already added one. - pub(crate) fn get_type_param( - &self, - definition: &clang::Cursor, - ) -> Option { + pub(crate) fn get_type_param(&self, definition: &Cursor) -> Option { assert_eq!( definition.kind(), clang_sys::CXCursor_TemplateTypeParameter ); - self.type_params.get(definition).cloned() + self.type_params.get(definition).copied() } // TODO: Move all this syntax crap to other part of the code. @@ -880,7 +865,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" "abstract" | "alignof" | "as" | "async" | "await" | "become" | "box" | "break" | "const" | "continue" | "crate" | "do" | "dyn" | "else" | "enum" | "extern" | "false" | "final" | - "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | + "fn" | "for" | "gen" | "if" | "impl" | "in" | "let" | "loop" | "macro" | "match" | "mod" | "move" | "mut" | "offsetof" | "override" | "priv" | "proc" | "pub" | "pure" | "ref" | "return" | "Self" | "self" | "sizeof" | "static" | @@ -933,23 +918,20 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Gather all the unresolved type references. fn collect_typerefs( &mut self, - ) -> Vec<(ItemId, clang::Type, clang::Cursor, Option)> { + ) -> Vec<(ItemId, clang::Type, Cursor, Option)> { debug_assert!(!self.collected_typerefs); self.collected_typerefs = true; let mut typerefs = vec![]; for (id, item) in self.items() { let kind = item.kind(); - let ty = match kind.as_type() { - Some(ty) => ty, - None => continue, - }; + let Some(ty) = kind.as_type() else { continue }; if let TypeKind::UnresolvedTypeRef(ref ty, loc, parent_id) = *ty.kind() { typerefs.push((id, *ty, loc, parent_id)); - }; + } } typerefs } @@ -1005,7 +987,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" let result = f(self, &mut item); - let existing = mem::replace(&mut self.items[id.0], Some(item)); + let existing = self.items[id.0].replace(item); assert!(existing.is_none()); result @@ -1080,9 +1062,8 @@ If you encounter an error missing from this list, please file an issue or a PR!" // Calls to `canonical_name` are expensive, so eagerly filter out // items that cannot be replaced. - let ty = match item.kind().as_type() { - Some(ty) => ty, - None => continue, + let Some(ty) = item.kind().as_type() else { + continue; }; match *ty.kind() { @@ -1111,7 +1092,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" } for (id, replacement_id) in replacements { - debug!("Replacing {:?} with {:?}", id, replacement_id); + debug!("Replacing {id:?} with {replacement_id:?}"); let new_parent = { let item_id: ItemId = id.into(); let item = self.items[item_id.0].as_mut().unwrap(); @@ -1148,7 +1129,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" .chain(Some(immut_self.root_module.into())) .find(|id| { let item = immut_self.resolve_item(*id); - item.as_module().map_or(false, |m| { + item.as_module().is_some_and(|m| { m.children().contains(&replacement_id.into()) }) }) @@ -1236,7 +1217,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// When the `__testing_only_extra_assertions` feature is enabled, this /// function walks the IR graph and asserts that we do not have any edges - /// referencing an ItemId for which we do not have an associated IR item. + /// referencing an `ItemId` for which we do not have an associated IR item. fn assert_no_dangling_references(&self) { if cfg!(feature = "__testing_only_extra_assertions") { for _ in self.assert_no_dangling_item_traversal() { @@ -1247,9 +1228,9 @@ If you encounter an error missing from this list, please file an issue or a PR!" fn assert_no_dangling_item_traversal( &self, - ) -> traversal::AssertNoDanglingItemsTraversal { + ) -> traversal::AssertNoDanglingItemsTraversal<'_> { assert!(self.in_codegen_phase()); - assert!(self.current_module == self.root_module); + assert_eq!(self.current_module, self.root_module); let roots = self.items().map(|(id, _)| id); traversal::AssertNoDanglingItemsTraversal::new( @@ -1265,7 +1246,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" fn assert_every_item_in_a_module(&self) { if cfg!(feature = "__testing_only_extra_assertions") { assert!(self.in_codegen_phase()); - assert!(self.current_module == self.root_module); + assert_eq!(self.current_module, self.root_module); for (id, _item) in self.items() { if id == self.root_module { @@ -1283,19 +1264,13 @@ If you encounter an error missing from this list, please file an issue or a PR!" id.ancestors(self) .chain(Some(self.root_module.into())) .any(|ancestor| { - debug!( - "Checking if {:?} is a child of {:?}", - id, ancestor - ); + debug!("Checking if {id:?} is a child of {ancestor:?}"); self.resolve_item(ancestor) .as_module() - .map_or(false, |m| { - m.children().contains(&id) - }) + .is_some_and(|m| m.children().contains(&id)) }) }, - "{:?} should be in some ancestor module's children set", - id + "{id:?} should be in some ancestor module's children set" ); } } @@ -1320,7 +1295,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" .as_ref() .unwrap() .get(&id) - .cloned() + .copied() .unwrap_or(SizednessResult::ZeroSized) } @@ -1344,7 +1319,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" .as_ref() .unwrap() .get(&id.into()) - .cloned() + .copied() .unwrap_or(HasVtableResult::No) } @@ -1424,8 +1399,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.used_template_parameters .as_ref() .expect("should have found template parameter usage if we're in codegen") - .get(&item) - .map_or(false, |items_used_params| items_used_params.contains(&template_param)) + .get(&item).is_some_and(|items_used_params| items_used_params.contains(&template_param)) } /// Return `true` if `item` uses any unbound, generic template parameters, @@ -1444,7 +1418,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" "should have template parameter usage info in codegen phase", ) .get(&item) - .map_or(false, |used| !used.is_empty()) + .is_some_and(|used| !used.is_empty()) } // This deserves a comment. Builtin types don't get a valid declaration, so @@ -1456,11 +1430,11 @@ If you encounter an error missing from this list, please file an issue or a PR!" // If at some point we care about the memory here, probably a map TypeKind // -> builtin type ItemId would be the best to improve that. fn add_builtin_item(&mut self, item: Item) { - debug!("add_builtin_item: item = {:?}", item); + debug!("add_builtin_item: item = {item:?}"); debug_assert!(item.kind().is_type()); self.add_item_to_module(&item); let id = item.id(); - let old_item = mem::replace(&mut self.items[id.0], Some(item)); + let old_item = self.items[id.0].replace(item); assert!(old_item.is_none(), "Inserted type twice?"); } @@ -1515,7 +1489,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" let item_id = item_id.into(); match self.resolve_item_fallible(item_id) { Some(item) => item, - None => panic!("Not an item: {:?}", item_id), + None => panic!("Not an item: {item_id:?}"), } } @@ -1530,11 +1504,11 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// correct type definition afterwards. /// /// TODO(emilio): We could consider doing this only when - /// declaration.lexical_parent() != definition.lexical_parent(), but it's + /// `declaration.lexical_parent() != definition.lexical_parent()`, but it's /// not sure it's worth it. pub(crate) fn add_semantic_parent( &mut self, - definition: clang::Cursor, + definition: Cursor, parent_id: ItemId, ) { self.semantic_parents.insert(definition, parent_id); @@ -1543,9 +1517,9 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Returns a known semantic parent for a given definition. pub(crate) fn known_semantic_parent( &self, - definition: clang::Cursor, + definition: Cursor, ) -> Option { - self.semantic_parents.get(&definition).cloned() + self.semantic_parents.get(&definition).copied() } /// Given a cursor pointing to the location of a template instantiation, @@ -1593,7 +1567,6 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.currently_parsed_types() .iter() .find(|partial_ty| *partial_ty.decl() == referenced) - .cloned() }) .and_then(|template_decl| { let num_template_params = @@ -1618,7 +1591,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// function template declarations(!?!??!). /// /// The only way to do this is manually inspecting the AST and looking for - /// TypeRefs and TemplateRefs inside. This, unfortunately, doesn't work for + /// `TypeRefs` and `TemplateRefs` inside. This, unfortunately, doesn't work for /// more complex cases, see the comment on the assertion below. /// /// To add insult to injury, the AST itself has structure that doesn't make @@ -1649,7 +1622,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" with_id: ItemId, template: TypeId, ty: &clang::Type, - location: clang::Cursor, + location: Cursor, ) -> Option { let num_expected_args = self.resolve_type(template).num_self_template_params(self); @@ -1782,8 +1755,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" // Bypass all the validations in add_item explicitly. debug!( "instantiate_template: inserting nested \ - instantiation item: {:?}", - sub_item + instantiation item: {sub_item:?}" ); self.add_item_to_module(&sub_item); debug_assert_eq!(sub_id, sub_item.id()); @@ -1793,8 +1765,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" } _ => { warn!( - "Found template arg cursor we can't handle: {:?}", - child + "Found template arg cursor we can't handle: {child:?}" ); found_const_arg = true; } @@ -1845,7 +1816,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" ); // Bypass all the validations in add_item explicitly. - debug!("instantiate_template: inserting item: {:?}", item); + debug!("instantiate_template: inserting item: {item:?}"); self.add_item_to_module(&item); debug_assert_eq!(with_id, item.id()); self.items[with_id.0] = Some(item); @@ -1865,7 +1836,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" .usr() .and_then(|usr| self.types.get(&TypeKey::Usr(usr))) }) - .cloned() + .copied() } /// Looks up for an already resolved type, either because it's builtin, or @@ -1875,19 +1846,15 @@ If you encounter an error missing from this list, please file an issue or a PR!" with_id: ItemId, parent_id: Option, ty: &clang::Type, - location: Option, + location: Option, ) -> Option { use clang_sys::{CXCursor_TypeAliasTemplateDecl, CXCursor_TypeRef}; - debug!( - "builtin_or_resolved_ty: {:?}, {:?}, {:?}, {:?}", - ty, location, with_id, parent_id - ); + debug!("builtin_or_resolved_ty: {ty:?}, {location:?}, {with_id:?}, {parent_id:?}"); if let Some(decl) = ty.canonical_declaration(location.as_ref()) { if let Some(id) = self.get_resolved_type(&decl) { debug!( - "Already resolved ty {:?}, {:?}, {:?} {:?}", - id, decl, ty, location + "Already resolved ty {id:?}, {decl:?}, {ty:?} {location:?}" ); // If the declaration already exists, then either: // @@ -2012,6 +1979,9 @@ If you encounter an error missing from this list, please file an issue or a PR!" CXType_Short => TypeKind::Int(IntKind::Short), CXType_UShort => TypeKind::Int(IntKind::UShort), CXType_WChar => TypeKind::Int(IntKind::WChar), + CXType_Char16 if self.options().use_distinct_char16_t => { + TypeKind::Int(IntKind::Char16) + } CXType_Char16 => TypeKind::Int(IntKind::U16), CXType_Char32 => TypeKind::Int(IntKind::U32), CXType_Long => TypeKind::Int(IntKind::Long), @@ -2035,8 +2005,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" CXType_LongDouble => FloatKind::LongDouble, CXType_Float128 => FloatKind::Float128, _ => panic!( - "Non floating-type complex? {:?}, {:?}", - ty, float_type, + "Non floating-type complex? {ty:?}, {float_type:?}", ), }; TypeKind::Complex(float_kind) @@ -2085,8 +2054,11 @@ If you encounter an error missing from this list, please file an issue or a PR!" let mut header_names_to_compile = Vec::new(); let mut header_paths = Vec::new(); - let mut header_contents = String::new(); - for input_header in self.options.input_headers.iter() { + let mut header_includes = Vec::new(); + let single_header = self.options().input_headers.last().cloned()?; + for input_header in &self.options.input_headers + [..self.options.input_headers.len() - 1] + { let path = Path::new(input_header.as_ref()); if let Some(header_path) = path.parent() { if header_path == Path::new("") { @@ -2098,50 +2070,32 @@ If you encounter an error missing from this list, please file an issue or a PR!" header_paths.push("."); } let header_name = path.file_name()?.to_str()?; + header_includes.push(header_name.to_string()); header_names_to_compile .push(header_name.split(".h").next()?.to_string()); - header_contents += - format!("\n#include <{header_name}>").as_str(); } - let header_to_precompile = format!( + let pch = format!( "{}/{}", match self.options().clang_macro_fallback_build_dir { Some(ref path) => path.as_os_str().to_str()?, None => ".", }, - header_names_to_compile.join("-") + "-precompile.h" + header_names_to_compile.join("-") + "-precompile.h.pch" ); - let pch = header_to_precompile.clone() + ".pch"; - - let mut header_to_precompile_file = OpenOptions::new() - .create(true) - .truncate(true) - .write(true) - .open(&header_to_precompile) - .ok()?; - header_to_precompile_file - .write_all(header_contents.as_bytes()) - .ok()?; - - let mut c_args = Vec::new(); + + let mut c_args = self.options.fallback_clang_args.clone(); c_args.push("-x".to_string().into_boxed_str()); c_args.push("c-header".to_string().into_boxed_str()); for header_path in header_paths { c_args.push(format!("-I{header_path}").into_boxed_str()); } - c_args.extend( - self.options - .clang_args - .iter() - .filter(|next| { - !self.options.input_headers.contains(next) && - next.as_ref() != "-include" - }) - .cloned(), - ); + for header_include in header_includes { + c_args.push("-include".to_string().into_boxed_str()); + c_args.push(header_include.into_boxed_str()); + } let mut tu = clang::TranslationUnit::parse( &index, - &header_to_precompile, + &single_header, &c_args, &[], clang_sys::CXTranslationUnit_ForSerialization, @@ -2152,23 +2106,18 @@ If you encounter an error missing from this list, please file an issue or a PR!" "-include-pch".to_string().into_boxed_str(), pch.clone().into_boxed_str(), ]; - c_args.extend( - self.options - .clang_args - .clone() - .iter() - .filter(|next| { - !self.options.input_headers.contains(next) && - next.as_ref() != "-include" - }) - .cloned(), - ); - self.fallback_tu = Some(clang::FallbackTranslationUnit::new( - file, - header_to_precompile, - pch, - &c_args, - )?); + let mut skip_next = false; + for arg in &self.options.fallback_clang_args { + if arg.as_ref() == "-include" { + skip_next = true; + } else if skip_next { + skip_next = false; + } else { + c_args.push(arg.clone()); + } + } + self.fallback_tu = + Some(clang::FallbackTranslationUnit::new(file, pch, &c_args)?); } self.fallback_tu.as_mut() @@ -2209,19 +2158,14 @@ If you encounter an error missing from this list, please file an issue or a PR!" pub(crate) fn replace(&mut self, name: &[String], potential_ty: ItemId) { match self.replacements.entry(name.into()) { Entry::Vacant(entry) => { - debug!( - "Defining replacement for {:?} as {:?}", - name, potential_ty - ); + debug!("Defining replacement for {name:?} as {potential_ty:?}"); entry.insert(potential_ty); } Entry::Occupied(occupied) => { warn!( - "Replacement for {:?} already defined as {:?}; \ - ignoring duplicate replacement definition as {:?}", - name, + "Replacement for {name:?} already defined as {:?}; \ + ignoring duplicate replacement definition as {potential_ty:?}", occupied.get(), - potential_ty ); } } @@ -2256,7 +2200,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// namespace. fn tokenize_namespace( &self, - cursor: &clang::Cursor, + cursor: &Cursor, ) -> (Option, ModuleKind) { assert_eq!( cursor.kind(), @@ -2267,7 +2211,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" let mut module_name = None; let spelling = cursor.spelling(); if !spelling.is_empty() { - module_name = Some(spelling) + module_name = Some(spelling); } let mut kind = ModuleKind::Normal; @@ -2307,33 +2251,31 @@ If you encounter an error missing from this list, please file an issue or a PR!" ); } break; - } else { - // This is _likely_, but not certainly, a macro that's - // been placed just before the namespace keyword. - // Unfortunately, clang tokens don't let us easily see - // through the ifdef tokens, so we don't know what this - // token should really be. Instead of panicking though, - // we warn the user that we assumed the token was blank, - // and then move on. - // - // See also https://github.com/rust-lang/rust-bindgen/issues/1676. - warn!( - "Ignored unknown namespace prefix '{}' at {:?} in {:?}", - String::from_utf8_lossy(name), - token, - cursor - ); } + // This is _likely_, but not certainly, a macro that's + // been placed just before the namespace keyword. + // Unfortunately, clang tokens don't let us easily see + // through the ifdef tokens, so we don't know what this + // token should really be. Instead of panicking though, + // we warn the user that we assumed the token was blank, + // and then move on. + // + // See also https://github.com/rust-lang/rust-bindgen/issues/1676. + warn!("Ignored unknown namespace prefix '{}' at {token:?} in {cursor:?}", String::from_utf8_lossy(name)); } } } + if cursor.is_inline_namespace() { + kind = ModuleKind::Inline; + } + (module_name, kind) } - /// Given a CXCursor_Namespace cursor, return the item ID of the + /// Given a `CXCursor_Namespace` cursor, return the item ID of the /// corresponding module, or create one on the fly. - pub(crate) fn module(&mut self, cursor: clang::Cursor) -> ModuleId { + pub(crate) fn module(&mut self, cursor: Cursor) -> ModuleId { use clang_sys::*; assert_eq!(cursor.kind(), CXCursor_Namespace, "Be a nice person"); let cursor = cursor.canonical(); @@ -2384,7 +2326,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// allowlisted. pub(crate) fn allowlisted_items(&self) -> &ItemSet { assert!(self.in_codegen_phase()); - assert!(self.current_module == self.root_module); + assert_eq!(self.current_module, self.root_module); self.allowlisted.as_ref().unwrap() } @@ -2397,7 +2339,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" derive_trait: DeriveTrait, ) -> CanDerive { assert!(self.in_codegen_phase()); - assert!(self.current_module == self.root_module); + assert_eq!(self.current_module, self.root_module); *self .blocklisted_types_implement_traits @@ -2445,14 +2387,14 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Get a reference to the set of items we should generate. pub(crate) fn codegen_items(&self) -> &ItemSet { assert!(self.in_codegen_phase()); - assert!(self.current_module == self.root_module); + assert_eq!(self.current_module, self.root_module); self.codegen_items.as_ref().unwrap() } /// Compute the allowlisted items set and populate `self.allowlisted`. fn compute_allowlisted_and_codegen_items(&mut self) { assert!(self.in_codegen_phase()); - assert!(self.current_module == self.root_module); + assert_eq!(self.current_module, self.root_module); assert!(self.allowlisted.is_none()); let _t = self.timer("compute_allowlisted_and_codegen_items"); @@ -2497,7 +2439,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" } let name = item.path_for_allowlisting(self)[1..].join("::"); - debug!("allowlisted_items: testing {:?}", name); + debug!("allowlisted_items: testing {name:?}"); if self.options().allowlisted_items.matches(&name) { return true; @@ -2551,9 +2493,8 @@ If you encounter an error missing from this list, please file an issue or a PR!" return false; } - let enum_ = match *ty.kind() { - TypeKind::Enum(ref e) => e, - _ => return false, + let TypeKind::Enum(ref enum_) = *ty.kind() else { + return false; }; if ty.name().is_some() { @@ -2646,9 +2587,26 @@ If you encounter an error missing from this list, please file an issue or a PR!" } } + /// Call if an opaque array is generated + pub(crate) fn generated_opaque_array(&self, align: usize) { + self.generated_opaque_array.borrow_mut().insert(align); + } + + /// Whether we need to generate the opaque array type + pub(crate) fn opaque_array_types_needed(&self) -> Vec { + let mut alignments = self + .generated_opaque_array + .borrow() + .iter() + .copied() + .collect::>(); + alignments.sort_unstable(); + alignments + } + /// Call if a bindgen complex is generated pub(crate) fn generated_bindgen_complex(&self) { - self.generated_bindgen_complex.set(true) + self.generated_bindgen_complex.set(true); } /// Whether we need to generate the bindgen complex type @@ -2658,7 +2616,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Call if a bindgen float16 is generated pub(crate) fn generated_bindgen_float16(&self) { - self.generated_bindgen_float16.set(true) + self.generated_bindgen_float16.set(true); } /// Whether we need to generate the bindgen float16 type @@ -2831,7 +2789,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" !self.cannot_derive_hash.as_ref().unwrap().contains(&id) } - /// Compute whether we can derive PartialOrd, PartialEq or Eq. + /// Compute whether we can derive `PartialOrd`, `PartialEq` or `Eq`. fn compute_cannot_derive_partialord_partialeq_or_eq(&mut self) { let _t = self.timer("compute_cannot_derive_partialord_partialeq_or_eq"); assert!(self.cannot_derive_partialeq_or_partialord.is_none()); @@ -2866,7 +2824,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" .as_ref() .unwrap() .get(&id) - .cloned() + .copied() .unwrap_or(CanDerive::Yes) } @@ -3124,7 +3082,7 @@ impl TemplateParameters for PartialType { num_params += 1; } _ => {} - }; + } clang_sys::CXChildVisit_Continue }); num_params @@ -3135,7 +3093,7 @@ impl TemplateParameters for PartialType { } fn unused_regex_diagnostic(item: &str, name: &str, _ctx: &BindgenContext) { - warn!("unused option: {} {}", name, item); + warn!("unused option: {name} {item}"); #[cfg(feature = "experimental")] if _ctx.options().emit_diagnostics { @@ -3143,11 +3101,11 @@ fn unused_regex_diagnostic(item: &str, name: &str, _ctx: &BindgenContext) { Diagnostic::default() .with_title( - format!("Unused regular expression: `{}`.", item), + format!("Unused regular expression: `{item}`."), Level::Warning, ) .add_annotation( - format!("This regular expression was passed to `{}`.", name), + format!("This regular expression was passed to `{name}`."), Level::Note, ) .display(); diff --git a/bindgen/ir/derive.rs b/bindgen/ir/derive.rs index 5475ffdb22..3ee6476af9 100644 --- a/bindgen/ir/derive.rs +++ b/bindgen/ir/derive.rs @@ -125,6 +125,6 @@ impl ops::BitOr for CanDerive { impl ops::BitOrAssign for CanDerive { fn bitor_assign(&mut self, rhs: Self) { - *self = self.join(rhs) + *self = self.join(rhs); } } diff --git a/bindgen/ir/dot.rs b/bindgen/ir/dot.rs index d5c1a42fdc..9bfc559f41 100644 --- a/bindgen/ir/dot.rs +++ b/bindgen/ir/dot.rs @@ -17,7 +17,7 @@ pub(crate) trait DotAttributes { out: &mut W, ) -> io::Result<()> where - W: io::Write; + W: Write; } /// Write a graphviz dot file containing our IR. @@ -41,7 +41,7 @@ where if is_allowlisted { "black" } else { "gray" } )?; item.dot_attributes(ctx, &mut dot_file)?; - writeln!(&mut dot_file, r#" >];"#)?; + writeln!(&mut dot_file, " >];")?; item.trace( ctx, @@ -52,10 +52,9 @@ where match writeln!( &mut dot_file, - "{} -> {} [label={:?}, color={}];", + "{} -> {} [label={edge_kind:?}, color={}];", id.as_usize(), sub_id.as_usize(), - edge_kind, if is_allowlisted { "black" } else { "gray" } ) { Ok(_) => {} diff --git a/bindgen/ir/enum_ty.rs b/bindgen/ir/enum_ty.rs index 70cf0eae88..9b08da3bce 100644 --- a/bindgen/ir/enum_ty.rs +++ b/bindgen/ir/enum_ty.rs @@ -59,7 +59,7 @@ impl Enum { ctx: &mut BindgenContext, ) -> Result { use clang_sys::*; - debug!("Enum::from_ty {:?}", ty); + debug!("Enum::from_ty {ty:?}"); if ty.kind() != CXType_Enum { return Err(ParseError::Continue); @@ -73,13 +73,13 @@ impl Enum { let variant_ty = repr.and_then(|r| ctx.resolve_type(r).safe_canonical_type(ctx)); - let is_bool = variant_ty.map_or(false, Type::is_bool); + let is_bool = variant_ty.is_some_and(Type::is_bool); // Assume signedness since the default type by the C standard is an int. let is_signed = variant_ty.map_or(true, |ty| match *ty.kind() { TypeKind::Int(ref int_kind) => int_kind.is_signed(), ref other => { - panic!("Since when enums can be non-integers? {:?}", other) + panic!("Since when enums can be non-integers? {other:?}") } }); @@ -310,14 +310,12 @@ impl EnumVariant { /// Returns whether this variant should be enforced to be a constant by code /// generation. pub(crate) fn force_constification(&self) -> bool { - self.custom_behavior - .map_or(false, |b| b == EnumVariantCustomBehavior::Constify) + self.custom_behavior == Some(EnumVariantCustomBehavior::Constify) } /// Returns whether the current variant should be hidden completely from the /// resulting rust enum. pub(crate) fn hidden(&self) -> bool { - self.custom_behavior - .map_or(false, |b| b == EnumVariantCustomBehavior::Hide) + self.custom_behavior == Some(EnumVariantCustomBehavior::Hide) } } diff --git a/bindgen/ir/function.rs b/bindgen/ir/function.rs index 1557843d03..6f8c00fa89 100644 --- a/bindgen/ir/function.rs +++ b/bindgen/ir/function.rs @@ -17,7 +17,7 @@ use std::str::FromStr; const RUST_DERIVE_FUNPTR_LIMIT: usize = 12; -/// What kind of a function are we looking at? +/// What kind of function are we looking at? #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub(crate) enum FunctionKind { /// A plain, free function. @@ -82,7 +82,7 @@ pub(crate) struct Function { /// The mangled name, that is, the symbol. mangled_name: Option, - /// The link name. If specified, overwrite mangled_name. + /// The link name. If specified, overwrite `mangled_name`. link_name: Option, /// The ID pointing to the current function signature. @@ -158,11 +158,7 @@ impl DotAttributes for Function { if let Some(ref mangled) = self.mangled_name { let mangled: String = mangled.chars().flat_map(|c| c.escape_default()).collect(); - writeln!( - out, - "mangled name{}", - mangled - )?; + writeln!(out, "mangled name{mangled}")?; } Ok(()) @@ -209,7 +205,7 @@ impl FromStr for Abi { "win64" => Ok(Self::Win64), "C-unwind" => Ok(Self::CUnwind), "system" => Ok(Self::System), - _ => Err(format!("Invalid or unknown ABI {:?}", s)), + _ => Err(format!("Invalid or unknown ABI {s:?}")), } } } @@ -251,8 +247,8 @@ pub(crate) enum ClangAbi { impl ClangAbi { /// Returns whether this Abi is known or not. - fn is_unknown(&self) -> bool { - matches!(*self, ClangAbi::Unknown(..)) + fn is_unknown(self) -> bool { + matches!(self, ClangAbi::Unknown(..)) } } @@ -261,8 +257,7 @@ impl quote::ToTokens for ClangAbi { match *self { Self::Known(abi) => abi.to_tokens(tokens), Self::Unknown(cc) => panic!( - "Cannot turn unknown calling convention to tokens: {:?}", - cc + "Cannot turn unknown calling convention to tokens: {cc:?}" ), } } @@ -295,15 +290,15 @@ pub(crate) struct FunctionSig { fn get_abi(cc: CXCallingConv) -> ClangAbi { use clang_sys::*; match cc { - CXCallingConv_Default => ClangAbi::Known(Abi::C), - CXCallingConv_C => ClangAbi::Known(Abi::C), + CXCallingConv_Default | CXCallingConv_C => ClangAbi::Known(Abi::C), CXCallingConv_X86StdCall => ClangAbi::Known(Abi::Stdcall), CXCallingConv_X86FastCall => ClangAbi::Known(Abi::Fastcall), CXCallingConv_X86ThisCall => ClangAbi::Known(Abi::ThisCall), - CXCallingConv_X86VectorCall => ClangAbi::Known(Abi::Vectorcall), + CXCallingConv_X86VectorCall | CXCallingConv_AArch64VectorCall => { + ClangAbi::Known(Abi::Vectorcall) + } CXCallingConv_AAPCS => ClangAbi::Known(Abi::Aapcs), CXCallingConv_X86_64Win64 => ClangAbi::Known(Abi::Win64), - CXCallingConv_AArch64VectorCall => ClangAbi::Known(Abi::Vectorcall), other => ClangAbi::Unknown(other), } } @@ -423,7 +418,7 @@ impl FunctionSig { ctx: &mut BindgenContext, ) -> Result { use clang_sys::*; - debug!("FunctionSig::from_ty {:?} {:?}", ty, cursor); + debug!("FunctionSig::from_ty {ty:?} {cursor:?}"); // Skip function templates let kind = cursor.kind(); @@ -438,7 +433,7 @@ impl FunctionSig { spelling.starts_with("operator") && !clang::is_valid_identifier(spelling) }; - if is_operator(&spelling) { + if is_operator(&spelling) && !ctx.options().represent_cxx_operators { return Err(ParseError::Continue); } @@ -538,7 +533,10 @@ impl FunctionSig { let is_const = is_method && cursor.method_is_const(); let is_virtual = is_method && cursor.method_is_virtual(); let is_static = is_method && cursor.method_is_static(); - if !is_static && !is_virtual { + if !is_static && + (!is_virtual || + ctx.options().use_specific_virtual_function_receiver) + { let parent = cursor.semantic_parent(); let class = Item::parse(parent, None, ctx) .expect("Expected to parse the class"); @@ -601,7 +599,7 @@ impl FunctionSig { let abi = get_abi(call_conv); if abi.is_unknown() { - warn!("Unknown calling convention: {:?}", call_conv); + warn!("Unknown calling convention: {call_conv:?}"); } Ok(Self { @@ -726,18 +724,18 @@ impl ClangSubItemParser for Function { ) -> Result, ParseError> { use clang_sys::*; - let kind = match FunctionKind::from_cursor(&cursor) { - None => return Err(ParseError::Continue), - Some(k) => k, + let Some(kind) = FunctionKind::from_cursor(&cursor) else { + return Err(ParseError::Continue); }; - debug!("Function::parse({:?}, {:?})", cursor, cursor.cur_type()); + debug!("Function::parse({cursor:?}, {:?})", cursor.cur_type()); let visibility = cursor.visibility(); if visibility != CXVisibility_Default { return Err(ParseError::Continue); } - - if cursor.access_specifier() == CX_CXXPrivate { + if cursor.access_specifier() == CX_CXXPrivate && + !context.options().generate_private_functions + { return Err(ParseError::Continue); } @@ -749,9 +747,7 @@ impl ClangSubItemParser for Function { }; if cursor.is_inlined_function() || - cursor - .definition() - .map_or(false, |x| x.is_inlined_function()) + cursor.definition().is_some_and(|x| x.is_inlined_function()) { if !context.options().generate_inline_functions && !context.options().wrap_static_fns @@ -759,7 +755,9 @@ impl ClangSubItemParser for Function { return Err(ParseError::Continue); } - if cursor.is_deleted_function() { + if cursor.is_deleted_function() && + !context.options().generate_deleted_functions + { return Err(ParseError::Continue); } diff --git a/bindgen/ir/int.rs b/bindgen/ir/int.rs index 4251b3753a..217fc11efa 100644 --- a/bindgen/ir/int.rs +++ b/bindgen/ir/int.rs @@ -54,9 +54,12 @@ pub enum IntKind { /// A 16-bit signed integer. I16, - /// Either a `char16_t` or a `wchar_t`. + /// A 16-bit integer, used only for enum size representation. U16, + /// The C++ type `char16_t`, which is its own type (unlike in C). + Char16, + /// A 32-bit signed integer. I32, @@ -94,14 +97,12 @@ impl IntKind { // to know whether it is or not right now (unlike char, there's no // WChar_S / WChar_U). Bool | UChar | UShort | UInt | ULong | ULongLong | U8 | U16 | - WChar | U32 | U64 | U128 => false, + Char16 | WChar | U32 | U64 | U128 => false, SChar | Short | Int | Long | LongLong | I8 | I16 | I32 | I64 | I128 => true, - Char { is_signed } => is_signed, - - Custom { is_signed, .. } => is_signed, + Char { is_signed } | Custom { is_signed, .. } => is_signed, } } @@ -112,16 +113,11 @@ impl IntKind { use self::IntKind::*; Some(match *self { Bool | UChar | SChar | U8 | I8 | Char { .. } => 1, - U16 | I16 => 2, + U16 | I16 | Char16 => 2, U32 | I32 => 4, U64 | I64 => 8, I128 | U128 => 16, _ => return None, }) } - - /// Whether this type's signedness matches the value. - pub(crate) fn signedness_matches(&self, val: i64) -> bool { - val >= 0 || self.is_signed() - } } diff --git a/bindgen/ir/item.rs b/bindgen/ir/item.rs index 94abe4a86b..eea02cce6c 100644 --- a/bindgen/ir/item.rs +++ b/bindgen/ir/item.rs @@ -1,6 +1,8 @@ //! Bindgen's core intermediate representation type. -use super::super::codegen::{EnumVariation, CONSTIFIED_ENUM_MODULE_REPR_NAME}; +use super::super::codegen::{ + AliasVariation, EnumVariation, CONSTIFIED_ENUM_MODULE_REPR_NAME, +}; use super::analysis::{HasVtable, HasVtableResult, Sizedness, SizednessResult}; use super::annotations::Annotations; use super::comp::{CompKind, MethodKind}; @@ -12,11 +14,11 @@ use super::derive::{ use super::dot::DotAttributes; use super::function::{Function, FunctionKind}; use super::item_kind::ItemKind; -use super::layout::Opaque; use super::module::Module; use super::template::{AsTemplateParam, TemplateParameters}; use super::traversal::{EdgeKind, Trace, Tracer}; use super::ty::{Type, TypeKind}; +use crate::callbacks::ItemInfo; use crate::clang; use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; @@ -44,7 +46,7 @@ pub(crate) trait ItemCanonicalName { /// The same, but specifies the path that needs to be followed to reach an item. /// -/// To contrast with canonical_name, here's an example: +/// To contrast with `canonical_name`, here's an example: /// /// ```c++ /// namespace foo { @@ -103,6 +105,7 @@ impl DebugOnlyItemSet { DebugOnlyItemSet } + #[allow(clippy::trivially_copy_pass_by_ref)] fn contains(&self, _id: &ItemId) -> bool { false } @@ -127,7 +130,7 @@ impl<'a> ItemAncestorsIter<'a> { } } -impl<'a> Iterator for ItemAncestorsIter<'a> { +impl Iterator for ItemAncestorsIter<'_> { type Item = ItemId; fn next(&mut self) -> Option { @@ -375,7 +378,7 @@ pub(crate) struct Item { /// The item's local ID, unique only amongst its siblings. Only used for /// anonymous items. /// - /// Lazily initialized in local_id(). + /// Lazily initialized in `local_id()`. /// /// Note that only structs, unions, and enums get a local type ID. In any /// case this is an implementation detail. @@ -449,7 +452,7 @@ impl Item { ctx: &mut BindgenContext, ) -> TypeId { let location = ty.declaration().location(); - let ty = Opaque::from_clang_ty(ty, ctx); + let ty = Type::new_opaque_from_clang_ty(ty, ctx); let kind = ItemKind::Type(ty); let parent = ctx.root_module().into(); ctx.add_item( @@ -492,7 +495,7 @@ impl Item { self.ancestors(ctx) .filter(|id| { - ctx.resolve_item(*id).as_module().map_or(false, |module| { + ctx.resolve_item(*id).as_module().is_some_and(|module| { !module.is_inline() || ctx.options().conservative_inline_namespaces }) @@ -582,9 +585,8 @@ impl Item { let mut parent = self.parent_id; loop { - let parent_item = match ctx.resolve_item_fallible(parent) { - Some(item) => item, - None => return false, + let Some(parent_item) = ctx.resolve_item_fallible(parent) else { + return false; }; if parent_item.id() == ctx.root_module() { @@ -669,7 +671,7 @@ impl Item { } } - /// Take out item NameOptions + /// Take out item `NameOptions` pub(crate) fn name<'a>( &'a self, ctx: &'a BindgenContext, @@ -717,7 +719,7 @@ impl Item { s } - /// Helper function for full_disambiguated_name + /// Helper function for `full_disambiguated_name` fn push_disambiguated_name( &self, ctx: &BindgenContext, @@ -727,7 +729,7 @@ impl Item { to.push_str(&self.canonical_name(ctx)); if let ItemKind::Type(ref ty) = *self.kind() { if let TypeKind::TemplateInstantiation(ref inst) = *ty.kind() { - to.push_str(&format!("_open{}_", level)); + let _ = write!(to, "_open{level}_"); for arg in inst.template_arguments() { arg.into_resolver() .through_type_refs() @@ -735,7 +737,7 @@ impl Item { .push_disambiguated_name(ctx, to, level + 1); to.push('_'); } - to.push_str(&format!("close{}", level)); + let _ = write!(to, "close{level}"); } } } @@ -786,22 +788,20 @@ impl Item { match *self.kind() { ItemKind::Var(ref var) => var.name().to_owned(), - ItemKind::Module(ref module) => { - module.name().map(ToOwned::to_owned).unwrap_or_else(|| { - format!("_bindgen_mod_{}", self.exposed_id(ctx)) - }) - } - ItemKind::Type(ref ty) => { - ty.sanitized_name(ctx).map(Into::into).unwrap_or_else(|| { - format!("_bindgen_ty_{}", self.exposed_id(ctx)) - }) - } + ItemKind::Module(ref module) => module.name().map_or_else( + || format!("_bindgen_mod_{}", self.exposed_id(ctx)), + ToOwned::to_owned, + ), + ItemKind::Type(ref ty) => ty.sanitized_name(ctx).map_or_else( + || format!("_bindgen_ty_{}", self.exposed_id(ctx)), + Into::into, + ), ItemKind::Function(ref fun) => { let mut name = fun.name().to_owned(); if let Some(idx) = self.overload_index(ctx) { if idx > 0 { - write!(&mut name, "{}", idx).unwrap(); + write!(&mut name, "{idx}").unwrap(); } } @@ -924,8 +924,19 @@ impl Item { let name = names.join("_"); let name = if opt.user_mangled == UserMangled::Yes { + let item_info = ItemInfo { + name: &name, + kind: match self.kind() { + ItemKind::Module(..) => crate::callbacks::ItemKind::Module, + ItemKind::Type(..) => crate::callbacks::ItemKind::Type, + ItemKind::Function(..) => { + crate::callbacks::ItemKind::Function + } + ItemKind::Var(..) => crate::callbacks::ItemKind::Var, + }, + }; ctx.options() - .last_callback(|callbacks| callbacks.item_name(&name)) + .last_callback(|callbacks| callbacks.item_name(item_info)) .unwrap_or(name) } else { name @@ -978,9 +989,8 @@ impl Item { // Do not jump through aliases, except for aliases that point to a type // with the same name, since we dont generate coe for them. let item = self.id.into_resolver().through_type_refs().resolve(ctx); - let type_ = match *item.kind() { - ItemKind::Type(ref type_) => type_, - _ => return false, + let ItemKind::Type(ref type_) = *item.kind() else { + return false; }; match *type_.kind() { @@ -1016,15 +1026,15 @@ impl Item { FunctionKind::Method(MethodKind::Constructor) => { cc.constructors() } - FunctionKind::Method(MethodKind::Destructor) | - FunctionKind::Method(MethodKind::VirtualDestructor { - .. - }) => cc.destructors(), - FunctionKind::Method(MethodKind::Static) | - FunctionKind::Method(MethodKind::Normal) | - FunctionKind::Method(MethodKind::Virtual { .. }) => { - cc.methods() - } + FunctionKind::Method( + MethodKind::Destructor | + MethodKind::VirtualDestructor { .. }, + ) => cc.destructors(), + FunctionKind::Method( + MethodKind::Static | + MethodKind::Normal | + MethodKind::Virtual { .. }, + ) => cc.methods(), }, } } @@ -1058,7 +1068,7 @@ impl Item { .map(|id| ctx.resolve_item(id)) .filter(|item| { item.id() == target.id() || - item.as_module().map_or(false, |module| { + item.as_module().is_some_and(|module| { !module.is_inline() || ctx.options().conservative_inline_namespaces }) @@ -1077,9 +1087,8 @@ impl Item { /// Returns a prefix for the canonical name when C naming is enabled. fn c_naming_prefix(&self) -> Option<&str> { - let ty = match self.kind { - ItemKind::Type(ref ty) => ty, - _ => return None, + let ItemKind::Type(ref ty) = self.kind else { + return None; }; Some(match ty.kind() { @@ -1096,6 +1105,20 @@ impl Item { pub(crate) fn must_use(&self, ctx: &BindgenContext) -> bool { self.annotations().must_use_type() || ctx.must_use_type_by_name(self) } + + /// Get the alias style for this item. + pub(crate) fn alias_style(&self, ctx: &BindgenContext) -> AliasVariation { + let name = self.canonical_name(ctx); + if ctx.options().type_alias.matches(&name) { + AliasVariation::TypeAlias + } else if ctx.options().new_type_alias.matches(&name) { + AliasVariation::NewType + } else if ctx.options().new_type_alias_deref.matches(&name) { + AliasVariation::NewTypeDeref + } else { + ctx.options().default_alias_style + } + } } impl IsOpaque for T @@ -1122,7 +1145,7 @@ impl IsOpaque for Item { "You're not supposed to call this yet" ); self.annotations.opaque() || - self.as_type().map_or(false, |ty| ty.is_opaque(ctx, self)) || + self.as_type().is_some_and(|ty| ty.is_opaque(ctx, self)) || ctx.opaque_by_name(self.path_for_allowlisting(ctx)) } } @@ -1133,14 +1156,14 @@ where { fn has_vtable(&self, ctx: &BindgenContext) -> bool { let id: ItemId = (*self).into(); - id.as_type_id(ctx).map_or(false, |id| { + id.as_type_id(ctx).is_some_and(|id| { !matches!(ctx.lookup_has_vtable(id), HasVtableResult::No) }) } fn has_vtable_ptr(&self, ctx: &BindgenContext) -> bool { let id: ItemId = (*self).into(); - id.as_type_id(ctx).map_or(false, |id| { + id.as_type_id(ctx).is_some_and(|id| { matches!(ctx.lookup_has_vtable(id), HasVtableResult::SelfHasVtable) }) } @@ -1420,11 +1443,7 @@ impl Item { CXCursor_UsingDirective | CXCursor_StaticAssert | CXCursor_FunctionTemplate => { - debug!( - "Unhandled cursor kind {:?}: {:?}", - cursor.kind(), - cursor - ); + debug!("Unhandled cursor kind {:?}: {cursor:?}", cursor.kind()); Err(ParseError::Continue) } @@ -1432,7 +1451,7 @@ impl Item { let file = cursor.get_included_file_name(); match file { None => { - warn!("Inclusion of a nameless file in {:?}", cursor); + warn!("Inclusion of a nameless file in {cursor:?}"); } Some(included_file) => { for cb in &ctx.options().parse_callbacks { @@ -1450,9 +1469,8 @@ impl Item { let spelling = cursor.spelling(); if !spelling.starts_with("operator") { warn!( - "Unhandled cursor kind {:?}: {:?}", + "Unhandled cursor kind {:?}: {cursor:?}", cursor.kind(), - cursor ); } Err(ParseError::Continue) @@ -1489,10 +1507,7 @@ impl Item { parent_id: Option, ctx: &mut BindgenContext, ) -> TypeId { - debug!( - "from_ty_or_ref_with_id: {:?} {:?}, {:?}, {:?}", - potential_id, ty, location, parent_id - ); + debug!("from_ty_or_ref_with_id: {potential_id:?} {ty:?}, {location:?}, {parent_id:?}"); if ctx.collected_typerefs() { debug!("refs already collected, resolving directly"); @@ -1512,11 +1527,11 @@ impl Item { &ty, Some(location), ) { - debug!("{:?} already resolved: {:?}", ty, location); + debug!("{ty:?} already resolved: {location:?}"); return ty; } - debug!("New unresolved type reference: {:?}, {:?}", ty, location); + debug!("New unresolved type reference: {ty:?}, {location:?}"); let is_const = ty.is_const(); let kind = TypeKind::UnresolvedTypeRef(ty, location, parent_id); @@ -1566,14 +1581,13 @@ impl Item { use clang_sys::*; debug!( - "Item::from_ty_with_id: {:?}\n\ - \tty = {:?},\n\ - \tlocation = {:?}", - id, ty, location + "Item::from_ty_with_id: {id:?}\n\ + \tty = {ty:?},\n\ + \tlocation = {location:?}", ); - if ty.kind() == clang_sys::CXType_Unexposed || - location.cur_type().kind() == clang_sys::CXType_Unexposed + if ty.kind() == CXType_Unexposed || + location.cur_type().kind() == CXType_Unexposed { if ty.is_associated_type() || location.cur_type().is_associated_type() @@ -1593,7 +1607,7 @@ impl Item { // ignore function bodies. See issue #2036.) if let Some(ref parent) = ty.declaration().fallible_semantic_parent() { if FunctionKind::from_cursor(parent).is_some() { - debug!("Skipping type declared inside function: {:?}", ty); + debug!("Skipping type declared inside function: {ty:?}"); return Ok(Item::new_opaque_type(id, ty, ctx)); } } @@ -1603,10 +1617,7 @@ impl Item { canonical_def.unwrap_or_else(|| ty.declaration()) }; - let comment = location - .raw_comment() - .or_else(|| decl.raw_comment()) - .or_else(|| location.raw_comment()); + let comment = location.raw_comment().or_else(|| decl.raw_comment()); let annotations = Annotations::new(&decl).or_else(|| Annotations::new(&location)); @@ -1640,7 +1651,7 @@ impl Item { .iter() .find(|ty| *ty.decl() == declaration_to_look_for) { - debug!("Avoiding recursion parsing type: {:?}", ty); + debug!("Avoiding recursion parsing type: {ty:?}"); // Unchecked because we haven't finished this type yet. return Ok(partial.id().as_type_id_unchecked()); } @@ -1706,13 +1717,11 @@ impl Item { if let Err(ParseError::Recurse) = result { warn!( "Unknown type, assuming named template type: \ - id = {:?}; spelling = {}", - id, + id = {id:?}; spelling = {}", ty.spelling() ); Item::type_param(Some(id), location, ctx) - .map(Ok) - .unwrap_or(Err(ParseError::Recurse)) + .ok_or(ParseError::Recurse) } else { result } @@ -1738,13 +1747,10 @@ impl Item { debug!( "Item::type_param:\n\ - \twith_id = {:?},\n\ - \tty = {} {:?},\n\ - \tlocation: {:?}", - with_id, + \twith_id = {with_id:?},\n\ + \tty = {} {ty:?},\n\ + \tlocation: {location:?}", ty.spelling(), - ty, - location ); if ty.kind() != clang_sys::CXType_Unexposed { @@ -1871,16 +1877,11 @@ impl Item { let parent = ctx.root_module().into(); if let Some(id) = ctx.get_type_param(&definition) { - if let Some(with_id) = with_id { - return Some(ctx.build_ty_wrapper( - with_id, - id, - Some(parent), - &ty, - )); + return Some(if let Some(with_id) = with_id { + ctx.build_ty_wrapper(with_id, id, Some(parent), &ty) } else { - return Some(id); - } + id + }); } // See tests/headers/const_tparam.hpp and diff --git a/bindgen/ir/layout.rs b/bindgen/ir/layout.rs index 85a553da31..ba570e3702 100644 --- a/bindgen/ir/layout.rs +++ b/bindgen/ir/layout.rs @@ -1,10 +1,6 @@ //! Intermediate representation for the physical layout of some type. -use super::derive::CanDerive; -use super::ty::{Type, TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT}; -use crate::clang; use crate::ir::context::BindgenContext; -use std::cmp; /// A type that represents the struct layout of a type. #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -19,9 +15,8 @@ pub(crate) struct Layout { #[test] fn test_layout_for_size() { - use std::mem; - - let ptr_size = mem::size_of::<*mut ()>(); + use std::mem::size_of; + let ptr_size = size_of::<*mut ()>(); assert_eq!( Layout::for_size_internal(ptr_size, ptr_size), Layout::new(ptr_size, ptr_size) @@ -34,14 +29,9 @@ fn test_layout_for_size() { impl Layout { /// Gets the integer type name for a given known size. - pub(crate) fn known_type_for_size( - ctx: &BindgenContext, - size: usize, - ) -> Option { + pub(crate) fn known_type_for_size(size: usize) -> Option { Some(match size { - 16 if ctx.options().rust_features.i128_and_u128 => { - syn::parse_quote! { u128 } - } + 16 => syn::parse_quote! { u128 }, 8 => syn::parse_quote! { u64 }, 4 => syn::parse_quote! { u32 }, 2 => syn::parse_quote! { u16 }, @@ -77,62 +67,4 @@ impl Layout { pub(crate) fn for_size(ctx: &BindgenContext, size: usize) -> Self { Self::for_size_internal(ctx.target_pointer_size(), size) } - - /// Get this layout as an opaque type. - pub(crate) fn opaque(&self) -> Opaque { - Opaque(*self) - } -} - -/// When we are treating a type as opaque, it is just a blob with a `Layout`. -#[derive(Clone, Debug, PartialEq, Eq)] -pub(crate) struct Opaque(pub(crate) Layout); - -impl Opaque { - /// Construct a new opaque type from the given clang type. - pub(crate) fn from_clang_ty( - ty: &clang::Type, - ctx: &BindgenContext, - ) -> Type { - let layout = Layout::new(ty.size(ctx), ty.align(ctx)); - let ty_kind = TypeKind::Opaque; - let is_const = ty.is_const(); - Type::new(None, Some(layout), ty_kind, is_const) - } - - /// Return the known rust type we should use to create a correctly-aligned - /// field with this layout. - pub(crate) fn known_rust_type_for_array( - &self, - ctx: &BindgenContext, - ) -> Option { - Layout::known_type_for_size(ctx, self.0.align) - } - - /// Return the array size that an opaque type for this layout should have if - /// we know the correct type for it, or `None` otherwise. - pub(crate) fn array_size(&self, ctx: &BindgenContext) -> Option { - if self.known_rust_type_for_array(ctx).is_some() { - Some(self.0.size / cmp::max(self.0.align, 1)) - } else { - None - } - } - - /// Return `true` if this opaque layout's array size will fit within the - /// maximum number of array elements that Rust allows deriving traits - /// with. Return `false` otherwise. - pub(crate) fn array_size_within_derive_limit( - &self, - ctx: &BindgenContext, - ) -> CanDerive { - if self - .array_size(ctx) - .map_or(false, |size| size <= RUST_DERIVE_IN_ARRAY_LIMIT) - { - CanDerive::Yes - } else { - CanDerive::Manually - } - } } diff --git a/bindgen/ir/module.rs b/bindgen/ir/module.rs index 5ec55e9048..4788cf4285 100644 --- a/bindgen/ir/module.rs +++ b/bindgen/ir/module.rs @@ -84,8 +84,8 @@ impl ClangSubItemParser for Module { let module_id = ctx.module(cursor); ctx.with_module(module_id, |ctx| { cursor.visit_sorted(ctx, |ctx, child| { - parse_one(ctx, child, Some(module_id.into())) - }) + parse_one(ctx, child, Some(module_id.into())); + }); }); Ok(ParseResult::AlreadyResolved(module_id.into())) diff --git a/bindgen/ir/objc.rs b/bindgen/ir/objc.rs index d7f7cc65a6..6cdadb131d 100644 --- a/bindgen/ir/objc.rs +++ b/bindgen/ir/objc.rs @@ -17,20 +17,20 @@ use clang_sys::CXCursor_ObjCSuperClassRef; use clang_sys::CXCursor_TemplateTypeParameter; use proc_macro2::{Ident, Span, TokenStream}; -/// Objective C interface as used in TypeKind +/// Objective-C interface as used in `TypeKind` /// -/// Also protocols and categories are parsed as this type +/// Also, protocols and categories are parsed as this type #[derive(Debug)] pub(crate) struct ObjCInterface { /// The name - /// like, NSObject + /// like, `NSObject` name: String, category: Option, is_protocol: bool, - /// The list of template names almost always, ObjectType or KeyType + /// The list of template names almost always, `ObjectType` or `KeyType` pub(crate) template_names: Vec, /// The list of protocols that this interface conforms to. @@ -53,7 +53,7 @@ pub(crate) struct ObjCMethod { name: String, /// Method name as converted to rust - /// like, dataWithBytes_length_ + /// like, `dataWithBytes_length`_ rust_name: String, signature: FunctionSig, @@ -77,17 +77,17 @@ impl ObjCInterface { } /// The name - /// like, NSObject + /// like, `NSObject` pub(crate) fn name(&self) -> &str { self.name.as_ref() } /// Formats the name for rust - /// Can be like NSObject, but with categories might be like NSObject_NSCoderMethods - /// and protocols are like PNSObject + /// Can be like `NSObject`, but with categories might be like `NSObject_NSCoderMethods` + /// and protocols are like `PNSObject` pub(crate) fn rust_name(&self) -> String { if let Some(ref cat) = self.category { - format!("{}_{}", self.name(), cat) + format!("{}_{cat}", self.name()) } else if self.is_protocol { format!("P{}", self.name()) } else { @@ -147,8 +147,8 @@ impl ObjCInterface { let needle = format!("P{}", c.spelling()); let items_map = ctx.items(); debug!( - "Interface {} conforms to {}, find the item", - interface.name, needle + "Interface {} conforms to {needle}, find the item", + interface.name, ); for (id, item) in items_map { @@ -163,10 +163,7 @@ impl ObjCInterface { ty.name() ); if Some(needle.as_ref()) == ty.name() { - debug!( - "Found conforming protocol {:?}", - item - ); + debug!("Found conforming protocol {item:?}"); interface.conforms_to.push(id); break; } @@ -230,12 +227,12 @@ impl ObjCMethod { } /// Method name as converted to rust - /// like, dataWithBytes_length_ + /// like, `dataWithBytes_length`_ pub(crate) fn rust_name(&self) -> &str { self.rust_name.as_ref() } - /// Returns the methods signature as FunctionSig + /// Returns the methods signature as `FunctionSig` pub(crate) fn signature(&self) -> &FunctionSig { &self.signature } @@ -262,10 +259,7 @@ impl ObjCMethod { // unless it is `crate`, `self`, `super` or `Self`, so we try to add the `_` // suffix to it and parse it. if ["crate", "self", "super", "Self"].contains(&name) { - Some(Ident::new( - &format!("{}_", name), - Span::call_site(), - )) + Some(Ident::new(&format!("{name}_"), Span::call_site())) } else { Some(Ident::new(name, Span::call_site())) } @@ -278,11 +272,11 @@ impl ObjCMethod { Some( syn::parse_str::(name) .or_else(|err| { - syn::parse_str::(&format!("r#{}", name)) + syn::parse_str::(&format!("r#{name}")) .map_err(|_| err) }) .or_else(|err| { - syn::parse_str::(&format!("{}_", name)) + syn::parse_str::(&format!("{name}_")) .map_err(|_| err) }) .expect("Invalid identifier"), @@ -300,20 +294,15 @@ impl ObjCMethod { } // Check right amount of arguments - assert!( - args.len() == split_name.len() - 1, - "Incorrect method name or arguments for objc method, {:?} vs {:?}", - args, - split_name - ); + assert_eq!(args.len(), split_name.len() - 1, "Incorrect method name or arguments for objc method, {args:?} vs {split_name:?}"); // Get arguments without type signatures to pass to `msg_send!` let mut args_without_types = vec![]; - for arg in args.iter() { + for arg in args { let arg = arg.to_string(); let name_and_sig: Vec<&str> = arg.split(' ').collect(); let name = name_and_sig[0]; - args_without_types.push(Ident::new(name, Span::call_site())) + args_without_types.push(Ident::new(name, Span::call_site())); } let args = split_name.into_iter().zip(args_without_types).map( diff --git a/bindgen/ir/template.rs b/bindgen/ir/template.rs index 59bd4bfde4..7f3667879d 100644 --- a/bindgen/ir/template.rs +++ b/bindgen/ir/template.rs @@ -77,27 +77,23 @@ use crate::clang; /// The following table depicts the results of each trait method when invoked on /// each of the declarations above: /// -/// +------+----------------------+--------------------------+-------------------------+---- -/// |Decl. | self_template_params | num_self_template_params | all_template_parameters | ... -/// +------+----------------------+--------------------------+-------------------------+---- -/// |Foo | T, U | 2 | T, U | ... -/// |Bar | V | 1 | T, U, V | ... -/// |Inner | | 0 | T, U | ... -/// |Lol | W | 1 | T, U, W | ... -/// |Wtf | X | 1 | T, U, X | ... -/// |Qux | | 0 | | ... -/// +------+----------------------+--------------------------+------------------------+---- +/// |Decl. | self_template_params | num_self_template_params | all_template_parameters | +/// |------|----------------------|--------------------------|-------------------------| +/// |Foo | T, U | 2 | T, U | +/// |Bar | V | 1 | T, U, V | +/// |Inner | | 0 | T, U | +/// |Lol | W | 1 | T, U, W | +/// |Wtf | X | 1 | T, U, X | +/// |Qux | | 0 | | /// -/// ----+------+-----+----------------------+ -/// ... |Decl. | ... | used_template_params | -/// ----+------+-----+----------------------+ -/// ... |Foo | ... | T, U | -/// ... |Bar | ... | V | -/// ... |Inner | ... | | -/// ... |Lol | ... | T | -/// ... |Wtf | ... | T | -/// ... |Qux | ... | | -/// ----+------+-----+----------------------+ +/// | Decl. | used_template_params | +/// |-------|----------------------| +/// | Foo | T, U | +/// | Bar | V | +/// | Inner | | +/// | Lol | T | +/// | Wtf | T | +/// | Qux | | pub(crate) trait TemplateParameters: Sized { /// Get the set of `ItemId`s that make up this template declaration's free /// template parameters. @@ -266,17 +262,14 @@ impl TemplateInstantiation { }) }; - let definition = match definition { - Some(def) => def, - None => { - if !ty.declaration().is_builtin() { - warn!( - "Could not find template definition for template \ + let Some(definition) = definition else { + if !ty.declaration().is_builtin() { + warn!( + "Could not find template definition for template \ instantiation" - ); - } - return None; + ); } + return None; }; let template_definition = diff --git a/bindgen/ir/traversal.rs b/bindgen/ir/traversal.rs index 17e24f701e..01f3a8bd50 100644 --- a/bindgen/ir/traversal.rs +++ b/bindgen/ir/traversal.rs @@ -235,7 +235,7 @@ pub(crate) fn codegen_edges(ctx: &BindgenContext, edge: Edge) -> bool { /// outgoing edges might not have been fully traversed yet) in an active /// traversal. pub(crate) trait TraversalStorage<'ctx> { - /// Construct a new instance of this TraversalStorage, for a new traversal. + /// Construct a new instance of this `TraversalStorage`, for a new traversal. fn new(ctx: &'ctx BindgenContext) -> Self; /// Add the given item to the storage. If the item has never been seen @@ -287,8 +287,7 @@ impl<'ctx> TraversalStorage<'ctx> for Paths<'ctx> { } path.reverse(); panic!( - "Found reference to dangling id = {:?}\nvia path = {:?}", - item, path + "Found reference to dangling id = {item:?}\nvia path = {path:?}" ); } @@ -345,7 +344,7 @@ where F: FnMut(ItemId, EdgeKind), { fn visit_kind(&mut self, item: ItemId, kind: EdgeKind) { - (*self)(item, kind) + (*self)(item, kind); } } @@ -438,7 +437,7 @@ where let is_newly_discovered = self.seen.add(self.currently_traversing, item); if is_newly_discovered { - self.queue.push(item) + self.queue.push(item); } } } diff --git a/bindgen/ir/ty.rs b/bindgen/ir/ty.rs index 6d4c5666dc..a53de31c6a 100644 --- a/bindgen/ir/ty.rs +++ b/bindgen/ir/ty.rs @@ -6,7 +6,7 @@ use super::dot::DotAttributes; use super::enum_ty::Enum; use super::function::FunctionSig; use super::item::{IsOpaque, Item}; -use super::layout::{Layout, Opaque}; +use super::layout::Layout; use super::objc::ObjCInterface; use super::template::{ AsTemplateParam, TemplateInstantiation, TemplateParameters, @@ -67,6 +67,17 @@ impl Type { } } + /// Construct an opaque item from a clang type. + pub(crate) fn new_opaque_from_clang_ty( + ty: &clang::Type, + ctx: &BindgenContext, + ) -> Self { + let layout = Layout::new(ty.size(ctx), ty.align(ctx)); + let ty_kind = TypeKind::Opaque; + let is_const = ty.is_const(); + Type::new(None, Some(layout), ty_kind, is_const) + } + /// Which kind of type is this? pub(crate) fn kind(&self) -> &TypeKind { &self.kind @@ -243,12 +254,12 @@ impl Type { } /// Takes `name`, and returns a suitable identifier representation for it. - fn sanitize_name(name: &str) -> Cow { + fn sanitize_name(name: &str) -> Cow<'_, str> { if clang::is_valid_identifier(name) { return Cow::Borrowed(name); } - let name = name.replace(|c| c == ' ' || c == ':' || c == '.', "_"); + let name = name.replace([' ', ':', '.'], "_"); Cow::Owned(name) } @@ -261,7 +272,7 @@ impl Type { TypeKind::Pointer(inner) => Some((inner, Cow::Borrowed("ptr"))), TypeKind::Reference(inner) => Some((inner, Cow::Borrowed("ref"))), TypeKind::Array(inner, length) => { - Some((inner, format!("array{}", length).into())) + Some((inner, format!("array{length}").into())) } _ => None, }; @@ -269,13 +280,13 @@ impl Type { ctx.resolve_item(inner) .expect_type() .sanitized_name(ctx) - .map(|name| format!("{}_{}", prefix, name).into()) + .map(|name| format!("{prefix}_{name}").into()) } else { self.name().map(Self::sanitize_name) } } - /// See safe_canonical_type. + /// See [`Self::safe_canonical_type`]. pub(crate) fn canonical_type<'tr>( &'tr self, ctx: &'tr BindgenContext, @@ -471,7 +482,7 @@ impl TypeKind { #[test] fn is_invalid_type_param_valid() { let ty = Type::new(Some("foo".into()), None, TypeKind::TypeParam, false); - assert!(!ty.is_invalid_type_param()) + assert!(!ty.is_invalid_type_param()); } #[test] @@ -482,38 +493,38 @@ fn is_invalid_type_param_valid_underscore_and_numbers() { TypeKind::TypeParam, false, ); - assert!(!ty.is_invalid_type_param()) + assert!(!ty.is_invalid_type_param()); } #[test] fn is_invalid_type_param_valid_unnamed_kind() { let ty = Type::new(Some("foo".into()), None, TypeKind::Void, false); - assert!(!ty.is_invalid_type_param()) + assert!(!ty.is_invalid_type_param()); } #[test] fn is_invalid_type_param_invalid_start() { let ty = Type::new(Some("1foo".into()), None, TypeKind::TypeParam, false); - assert!(ty.is_invalid_type_param()) + assert!(ty.is_invalid_type_param()); } #[test] fn is_invalid_type_param_invalid_remaining() { let ty = Type::new(Some("foo-".into()), None, TypeKind::TypeParam, false); - assert!(ty.is_invalid_type_param()) + assert!(ty.is_invalid_type_param()); } #[test] -#[should_panic] +#[should_panic(expected = "Unnamed named type")] fn is_invalid_type_param_unnamed() { let ty = Type::new(None, None, TypeKind::TypeParam, false); - assert!(ty.is_invalid_type_param()) + assert!(ty.is_invalid_type_param()); } #[test] fn is_invalid_type_param_empty_name() { - let ty = Type::new(Some("".into()), None, TypeKind::TypeParam, false); - assert!(ty.is_invalid_type_param()) + let ty = Type::new(Some(String::new()), None, TypeKind::TypeParam, false); + assert!(ty.is_invalid_type_param()); } impl TemplateParameters for Type { @@ -582,7 +593,7 @@ pub(crate) enum TypeKind { /// A compound type, that is, a class, struct, or union. Comp(CompInfo), - /// An opaque type that we just don't understand. All usage of this shoulf + /// An opaque type that we just don't understand. All usage of this should /// result in an opaque blob of bytes generated from the containing type's /// layout. Opaque, @@ -623,7 +634,7 @@ pub(crate) enum TypeKind { /// A pointer to an Apple block. BlockPointer(TypeId), - /// A reference to a type, as in: int& foo(). + /// A reference to a type, as in: int& `foo()`. Reference(TypeId), /// An instantiation of an abstract template definition with a set of @@ -634,15 +645,10 @@ pub(crate) enum TypeKind { /// itself, and postpones its resolution. /// /// These are gone in a phase after parsing where these are mapped to - /// already known types, and are converted to ResolvedTypeRef. + /// already known types, and are converted to `ResolvedTypeRef`. /// /// see tests/headers/typeref.hpp to see somewhere where this is a problem. - UnresolvedTypeRef( - clang::Type, - clang::Cursor, - /* parent_id */ - Option, - ), + UnresolvedTypeRef(clang::Type, Cursor, /* parent_id */ Option), /// An indirection to another type. /// @@ -685,7 +691,7 @@ impl Type { Some(location), ); if let Some(ty) = already_resolved { - debug!("{:?} already resolved: {:?}", ty, location); + debug!("{ty:?} already resolved: {location:?}"); return Ok(ParseResult::AlreadyResolved(ty.into())); } } @@ -700,8 +706,7 @@ impl Type { }; debug!( - "from_clang_ty: {:?}, ty: {:?}, loc: {:?}", - potential_id, ty, location + "from_clang_ty: {potential_id:?}, ty: {ty:?}, loc: {location:?}" ); debug!("currently_parsed_types: {:?}", ctx.currently_parsed_types()); @@ -711,7 +716,7 @@ impl Type { let mut ty_kind = ty.kind(); match location.kind() { CXCursor_ObjCProtocolDecl | CXCursor_ObjCCategoryDecl => { - ty_kind = CXType_ObjCInterface + ty_kind = CXType_ObjCInterface; } _ => {} } @@ -743,7 +748,7 @@ impl Type { opaque type instead." ); return Ok(ParseResult::New( - Opaque::from_clang_ty(&canonical_ty, ctx), + Self::new_opaque_from_clang_ty(&canonical_ty, ctx), None, )); } @@ -776,7 +781,7 @@ impl Type { // etc. !canonical_ty.spelling().contains("type-parameter") => { - debug!("Looking for canonical type: {:?}", canonical_ty); + debug!("Looking for canonical type: {canonical_ty:?}"); return Self::from_clang_ty( potential_id, &canonical_ty, @@ -797,10 +802,7 @@ impl Type { // Same here, with template specialisations we can safely // assume this is a Comp(..) } else if ty.is_fully_instantiated_template() { - debug!( - "Template specialization: {:?}, {:?} {:?}", - ty, location, canonical_ty - ); + debug!("Template specialization: {ty:?}, {location:?} {canonical_ty:?}"); let complex = CompInfo::from_ty( potential_id, ty, @@ -869,20 +871,17 @@ impl Type { Some(location), ctx, ); - match complex { - Ok(complex) => TypeKind::Comp(complex), - Err(_) => { - warn!( - "Could not create complex type \ - from class template or base \ - specifier, using opaque blob" - ); - let opaque = - Opaque::from_clang_ty(ty, ctx); - return Ok(ParseResult::New( - opaque, None, - )); - } + if let Ok(complex) = complex { + TypeKind::Comp(complex) + } else { + warn!( + "Could not create complex type \ + from class template or base \ + specifier, using opaque blob" + ); + let opaque = + Self::new_opaque_from_clang_ty(ty, ctx); + return Ok(ParseResult::New(opaque, None)); } } CXCursor_TypeAliasTemplateDecl => { @@ -930,16 +929,12 @@ impl Type { CXChildVisit_Continue }); - let inner_type = match inner { - Ok(inner) => inner, - Err(..) => { - warn!( - "Failed to parse template alias \ - {:?}", - location - ); - return Err(ParseError::Continue); - } + let Ok(inner_type) = inner else { + warn!( + "Failed to parse template alias \ + {location:?}" + ); + return Err(ParseError::Continue); }; TypeKind::TemplateAlias(inner_type, args) @@ -948,13 +943,7 @@ impl Type { let referenced = location.referenced().unwrap(); let referenced_ty = referenced.cur_type(); - debug!( - "TemplateRef: location = {:?}; referenced = \ - {:?}; referenced_ty = {:?}", - location, - referenced, - referenced_ty - ); + debug!("TemplateRef: location = {location:?}; referenced = {referenced:?}; referenced_ty = {referenced_ty:?}"); return Self::from_clang_ty( potential_id, @@ -969,11 +958,7 @@ impl Type { let referenced_ty = referenced.cur_type(); let declaration = referenced_ty.declaration(); - debug!( - "TypeRef: location = {:?}; referenced = \ - {:?}; referenced_ty = {:?}", - location, referenced, referenced_ty - ); + debug!("TypeRef: location = {location:?}; referenced = {referenced:?}; referenced_ty = {referenced_ty:?}"); let id = Item::from_ty_or_ref_with_id( potential_id, @@ -991,16 +976,11 @@ impl Type { } _ => { if ty.kind() == CXType_Unexposed { - warn!( - "Unexposed type {:?}, recursing inside, \ - loc: {:?}", - ty, - location - ); + warn!("Unexposed type {ty:?}, recursing inside, loc: {location:?}"); return Err(ParseError::Recurse); } - warn!("invalid type {:?}", ty); + warn!("invalid type {ty:?}"); return Err(ParseError::Continue); } } @@ -1008,7 +988,7 @@ impl Type { } CXType_Auto => { if canonical_ty == *ty { - debug!("Couldn't find deduced type: {:?}", ty); + debug!("Couldn't find deduced type: {ty:?}"); return Err(ParseError::Continue); } @@ -1148,7 +1128,7 @@ impl Type { TypeKind::Comp(complex) } - CXType_Vector => { + CXType_Vector | CXType_ExtVector => { let inner = Item::from_ty( ty.elem_type().as_ref().unwrap(), location, @@ -1203,10 +1183,8 @@ impl Type { } _ => { warn!( - "unsupported type: kind = {:?}; ty = {:?}; at {:?}", + "unsupported type: kind = {:?}; ty = {ty:?}; at {location:?}", ty.kind(), - ty, - location ); return Err(ParseError::Continue); } @@ -1217,8 +1195,7 @@ impl Type { let is_const = ty.is_const() || (ty.kind() == CXType_ConstantArray && - ty.elem_type() - .map_or(false, |element| element.is_const())); + ty.elem_type().is_some_and(|element| element.is_const())); let ty = Type::new(name, layout, kind, is_const); // TODO: maybe declaration.canonical()? @@ -1233,10 +1210,7 @@ impl Trace for Type { where T: Tracer, { - if self - .name() - .map_or(false, |name| context.is_stdint_type(name)) - { + if self.name().is_some_and(|name| context.is_stdint_type(name)) { // These types are special-cased in codegen and don't need to be traversed. return; } diff --git a/bindgen/ir/var.rs b/bindgen/ir/var.rs index 01c57704d3..9d72dcf06e 100644 --- a/bindgen/ir/var.rs +++ b/bindgen/ir/var.rs @@ -113,11 +113,7 @@ impl DotAttributes for Var { } if let Some(ref mangled) = self.mangled_name { - writeln!( - out, - "mangled name{}", - mangled - )?; + writeln!(out, "mangled name{mangled}")?; } Ok(()) @@ -129,31 +125,32 @@ fn default_macro_constant_type(ctx: &BindgenContext, value: i64) -> IntKind { ctx.options().default_macro_constant_type == MacroTypeVariation::Signed { - if value < i32::MIN as i64 || value > i32::MAX as i64 { + if value < i64::from(i32::MIN) || value > i64::from(i32::MAX) { IntKind::I64 } else if !ctx.options().fit_macro_constants || - value < i16::MIN as i64 || - value > i16::MAX as i64 + value < i64::from(i16::MIN) || + value > i64::from(i16::MAX) { IntKind::I32 - } else if value < i8::MIN as i64 || value > i8::MAX as i64 { + } else if value < i64::from(i8::MIN) || value > i64::from(i8::MAX) { IntKind::I16 } else { IntKind::I8 } - } else if value > u32::MAX as i64 { + } else if value > i64::from(u32::MAX) { IntKind::U64 - } else if !ctx.options().fit_macro_constants || value > u16::MAX as i64 { + } else if !ctx.options().fit_macro_constants || value > i64::from(u16::MAX) + { IntKind::U32 - } else if value > u8::MAX as i64 { + } else if value > i64::from(u8::MAX) { IntKind::U16 } else { IntKind::U8 } } -/// Parses tokens from a CXCursor_MacroDefinition pointing into a function-like -/// macro, and calls the func_macro callback. +/// Parses tokens from a `CXCursor_MacroDefinition` pointing into a function-like +/// macro, and calls the `func_macro` callback. fn handle_function_macro( cursor: &clang::Cursor, callbacks: &dyn crate::callbacks::ParseCallbacks, @@ -202,9 +199,8 @@ impl ClangSubItemParser for Var { let value = parse_macro(ctx, &cursor); - let (id, value) = match value { - Some(v) => v, - None => return Err(ParseError::Continue), + let Some((id, value)) = value else { + return Err(ParseError::Continue); }; assert!(!id.is_empty(), "Empty macro name?"); @@ -238,10 +234,7 @@ impl ClangSubItemParser for Var { assert_eq!(c.len_utf8(), 1); c as u8 } - CChar::Raw(c) => { - assert!(c <= u8::MAX as u64); - c as u8 - } + CChar::Raw(c) => u8::try_from(c).unwrap(), }; (TypeKind::Int(IntKind::U8), VarType::Char(c)) @@ -311,7 +304,7 @@ impl ClangSubItemParser for Var { ([CXType_ConstantArray, CXType_IncompleteArray] .contains(&ty.kind()) && ty.elem_type() - .map_or(false, |element| element.is_const())); + .is_some_and(|element| element.is_const())); let ty = match Item::from_ty(&ty, cursor, None, ctx) { Ok(ty) => ty, @@ -320,8 +313,7 @@ impl ClangSubItemParser for Var { matches!(ty.kind(), CXType_Auto | CXType_Unexposed), "Couldn't resolve constant type, and it \ wasn't an nondeductible auto type or unexposed \ - type: {:?}", - ty + type: {ty:?}" ); return Err(e); } @@ -335,21 +327,21 @@ impl ClangSubItemParser for Var { .safe_resolve_type(ty) .and_then(|t| t.safe_canonical_type(ctx)); - let is_integer = canonical_ty.map_or(false, |t| t.is_integer()); - let is_float = canonical_ty.map_or(false, |t| t.is_float()); + let is_integer = canonical_ty.is_some_and(|t| t.is_integer()); + let is_float = canonical_ty.is_some_and(|t| t.is_float()); // TODO: We could handle `char` more gracefully. // TODO: Strings, though the lookup is a bit more hard (we need // to look at the canonical type of the pointee too, and check // is char, u8, or i8 I guess). let value = if is_integer { - let kind = match *canonical_ty.unwrap().kind() { - TypeKind::Int(kind) => kind, - _ => unreachable!(), + let TypeKind::Int(kind) = *canonical_ty.unwrap().kind() + else { + unreachable!() }; let mut val = cursor.evaluate().and_then(|v| v.as_int()); - if val.is_none() || !kind.signedness_matches(val.unwrap()) { + if val.is_none() { val = get_integer_literal_from_cursor(&cursor); } @@ -404,7 +396,7 @@ fn parse_macro_clang_fallback( } let ftu = ctx.try_ensure_fallback_translation_unit()?; - let contents = format!("int main() {{ {}; }}", cursor.spelling(),); + let contents = format!("int main() {{ {}; }}", cursor.spelling()); ftu.reparse(&contents).ok()?; // Children of root node of AST let root_children = ftu.translation_unit().cursor().collect_children(); @@ -435,7 +427,11 @@ fn parse_macro( ) -> Option<(Vec, cexpr::expr::EvalResult)> { use cexpr::expr; - let cexpr_tokens = cursor.cexpr_tokens(); + let mut cexpr_tokens = cursor.cexpr_tokens(); + + for callbacks in &ctx.options().parse_callbacks { + callbacks.modify_macro(&cursor.spelling(), &mut cexpr_tokens); + } let parser = expr::IdentifierParser::new(ctx.parsed_macros()); @@ -482,10 +478,10 @@ fn get_integer_literal_from_cursor(cursor: &clang::Cursor) -> Option { fn duplicated_macro_diagnostic( macro_name: &str, - _location: crate::clang::SourceLocation, + _location: clang::SourceLocation, _ctx: &BindgenContext, ) { - warn!("Duplicated macro definition: {}", macro_name); + warn!("Duplicated macro definition: {macro_name}"); #[cfg(feature = "experimental")] // FIXME (pvdrz & amanjeev): This diagnostic message shows way too often to be actually diff --git a/bindgen/lib.rs b/bindgen/lib.rs index 3da4e61f1e..f2c8870e05 100644 --- a/bindgen/lib.rs +++ b/bindgen/lib.rs @@ -50,12 +50,11 @@ mod regex_set; pub use codegen::{ AliasVariation, EnumVariation, MacroTypeVariation, NonCopyUnionStyle, }; -#[cfg(feature = "__cli")] -pub use features::RUST_TARGET_STRINGS; -pub use features::{RustTarget, LATEST_STABLE_RUST}; +pub use features::{RustEdition, RustTarget, LATEST_STABLE_RUST}; pub use ir::annotations::FieldVisibilityKind; pub use ir::function::Abi; -pub use regex_set::RegexSet; +#[cfg(feature = "__cli")] +pub use options::cli::builder_from_flags; use codegen::CodegenError; use features::RustFeatures; @@ -71,11 +70,11 @@ use std::env; use std::ffi::OsStr; use std::fs::{File, OpenOptions}; use std::io::{self, Write}; +use std::mem::size_of; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::rc::Rc; use std::str::FromStr; -use std::sync::{Arc, OnceLock}; // Some convenient typedefs for a fast hash map and hash set. type HashMap = rustc_hash::FxHashMap; @@ -87,10 +86,12 @@ pub const DEFAULT_ANON_FIELDS_PREFIX: &str = "__bindgen_anon_"; const DEFAULT_NON_EXTERN_FNS_SUFFIX: &str = "__extern"; fn file_is_cpp(name_file: &str) -> bool { - name_file.ends_with(".hpp") || - name_file.ends_with(".hxx") || - name_file.ends_with(".hh") || - name_file.ends_with(".h++") + Path::new(name_file).extension().is_some_and(|ext| { + ext.eq_ignore_ascii_case("hpp") || + ext.eq_ignore_ascii_case("hxx") || + ext.eq_ignore_ascii_case("hh") || + ext.eq_ignore_ascii_case("h++") + }) } fn args_are_cpp(clang_args: &[Box]) -> bool { @@ -193,7 +194,7 @@ impl FromStr for Formatter { "rustfmt" => Ok(Self::Rustfmt), #[cfg(feature = "prettyplease")] "prettyplease" => Ok(Self::Prettyplease), - _ => Err(format!("`{}` is not a valid formatter", s)), + _ => Err(format!("`{s}` is not a valid formatter")), } } } @@ -207,7 +208,7 @@ impl std::fmt::Display for Formatter { Self::Prettyplease => "prettyplease", }; - s.fmt(f) + std::fmt::Display::fmt(&s, f) } } @@ -300,12 +301,11 @@ fn get_extra_clang_args( parse_callbacks: &[Rc], ) -> Vec { // Add any extra arguments from the environment to the clang command line. - let extra_clang_args = match get_target_dependent_env_var( + let Some(extra_clang_args) = get_target_dependent_env_var( parse_callbacks, "BINDGEN_EXTRA_CLANG_ARGS", - ) { - None => return vec![], - Some(s) => s, + ) else { + return vec![]; }; // Try to parse it with shell quoting. If we fail, make it one single big argument. @@ -318,6 +318,22 @@ fn get_extra_clang_args( impl Builder { /// Generate the Rust bindings using the options built up thus far. pub fn generate(mut self) -> Result { + // Keep rust_features synced with rust_target + self.options.rust_features = match self.options.rust_edition { + Some(edition) => { + if !edition.is_available(self.options.rust_target) { + return Err(BindgenError::UnsupportedEdition( + edition, + self.options.rust_target, + )); + } + RustFeatures::new(self.options.rust_target, edition) + } + None => { + RustFeatures::new_with_latest_edition(self.options.rust_target) + } + }; + // Add any extra arguments from the environment to the clang command line. self.options.clang_args.extend( get_extra_clang_args(&self.options.parse_callbacks) @@ -331,6 +347,18 @@ impl Builder { } // Transform input headers to arguments on the clang command line. + self.options.fallback_clang_args = self + .options + .clang_args + .iter() + .filter(|arg| { + !arg.starts_with("-MMD") && + !arg.starts_with("-MD") && + !arg.starts_with("--write-user-dependencies") && + !arg.starts_with("--user-dependencies") + }) + .cloned() + .collect::>(); self.options.clang_args.extend( self.options.input_headers [..self.options.input_headers.len().saturating_sub(1)] @@ -346,7 +374,7 @@ impl Builder { }) .collect::>(); - Bindings::generate(self.options, input_unsaved_files) + Bindings::generate(self.options, &input_unsaved_files) } /// Preprocess and dump the input header files to disk. @@ -527,25 +555,11 @@ impl BindgenOptions { for regex_set in self.abi_overrides.values_mut().chain(regex_sets) { regex_set.build(record_matches); } - - let rust_target = self.rust_target; - #[allow(deprecated)] - if rust_target <= RustTarget::Stable_1_30 { - deprecated_target_diagnostic(rust_target, self); - } - - // Disable `untagged_union` if the target does not support it. - if !self.rust_features.untagged_union { - self.untagged_union = false; - } } /// Update rust target version pub fn set_rust_target(&mut self, rust_target: RustTarget) { self.rust_target = rust_target; - - // Keep rust_features synced with rust_target - self.rust_features = rust_target.into(); } /// Get features supported by target Rust version @@ -560,7 +574,7 @@ impl BindgenOptions { self.parse_callbacks .iter() .filter_map(|cb| f(cb.as_ref())) - .last() + .next_back() } fn all_callbacks( @@ -579,36 +593,15 @@ impl BindgenOptions { fn process_comment(&self, comment: &str) -> String { let comment = comment::preprocess(comment); - self.parse_callbacks - .last() - .and_then(|cb| cb.process_comment(&comment)) + self.last_callback(|cb| cb.process_comment(&comment)) .unwrap_or(comment) } } -fn deprecated_target_diagnostic(target: RustTarget, _options: &BindgenOptions) { - warn!("The {} Rust target is deprecated. If you have a need to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues", target); - - #[cfg(feature = "experimental")] - if _options.emit_diagnostics { - use crate::diagnostics::{Diagnostic, Level}; - - let mut diagnostic = Diagnostic::default(); - diagnostic.with_title( - format!("The {} Rust target is deprecated.", target), - Level::Warning, - ); - diagnostic.add_annotation( - "This Rust target was passed to `--rust-target`", - Level::Info, - ); - diagnostic.add_annotation("If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues", Level::Help); - diagnostic.display(); - } -} - #[cfg(feature = "runtime")] fn ensure_libclang_is_loaded() { + use std::sync::{Arc, OnceLock}; + if clang_sys::is_loaded() { return; } @@ -644,6 +637,8 @@ pub enum BindgenError { ClangDiagnostic(String), /// Code generation reported an error. Codegen(CodegenError), + /// The passed edition is not available on that Rust target. + UnsupportedEdition(RustEdition, RustTarget), } impl std::fmt::Display for BindgenError { @@ -659,10 +654,13 @@ impl std::fmt::Display for BindgenError { write!(f, "header '{}' does not exist.", h.display()) } BindgenError::ClangDiagnostic(message) => { - write!(f, "clang diagnosed error: {}", message) + write!(f, "clang diagnosed error: {message}") } BindgenError::Codegen(err) => { - write!(f, "codegen error: {}", err) + write!(f, "codegen error: {err}") + } + BindgenError::UnsupportedEdition(edition, target) => { + write!(f, "edition {edition} is not available on Rust {target}") } } } @@ -685,29 +683,44 @@ pub(crate) const HOST_TARGET: &str = fn rust_to_clang_target(rust_target: &str) -> Box { const TRIPLE_HYPHENS_MESSAGE: &str = "Target triple should contain hyphens"; - let mut clang_target = rust_target.to_owned(); - - if clang_target.starts_with("riscv32") { - let idx = clang_target.find('-').expect(TRIPLE_HYPHENS_MESSAGE); + let mut triple: Vec<&str> = rust_target.split_terminator('-').collect(); - clang_target.replace_range(..idx, "riscv32"); - } else if clang_target.starts_with("riscv64") { - let idx = clang_target.find('-').expect(TRIPLE_HYPHENS_MESSAGE); + assert!(!triple.is_empty(), "{TRIPLE_HYPHENS_MESSAGE}"); + triple.resize(4, ""); - clang_target.replace_range(..idx, "riscv64"); - } else if clang_target.starts_with("aarch64-apple-") { - let idx = clang_target.find('-').expect(TRIPLE_HYPHENS_MESSAGE); - - clang_target.replace_range(..idx, "arm64"); + // RISC-V + if triple[0].starts_with("riscv32") { + triple[0] = "riscv32"; + } else if triple[0].starts_with("riscv64") { + triple[0] = "riscv64"; } - if clang_target.ends_with("-espidf") { - let idx = clang_target.rfind('-').expect(TRIPLE_HYPHENS_MESSAGE); + // Apple + if triple[1] == "apple" { + if triple[0] == "aarch64" { + triple[0] = "arm64"; + } + if triple[3] == "sim" { + triple[3] = "simulator"; + } + } - clang_target.replace_range((idx + 1).., "elf"); + // ESP-IDF + if triple[2] == "espidf" { + triple[2] = "elf"; } - clang_target.into() + triple + .iter() + .skip(1) + .fold(triple[0].to_string(), |triple, part| { + if part.is_empty() { + triple + } else { + triple + "-" + part + } + }) + .into() } /// Returns the effective target, and whether it was explicitly specified on the @@ -740,10 +753,22 @@ impl Bindings { /// Generate bindings for the given options. pub(crate) fn generate( mut options: BindgenOptions, - input_unsaved_files: Vec, + input_unsaved_files: &[clang::UnsavedFile], ) -> Result { ensure_libclang_is_loaded(); + #[cfg(feature = "runtime")] + match clang_sys::get_library().unwrap().version() { + None => { + warn!("Could not detect a Clang version, make sure you are using libclang 9 or newer"); + } + Some(version) => { + if version < clang_sys::Version::V9_0 { + warn!("Detected Clang version {version:?} which is unsupported and can cause invalid code generation, use libclang 9 or newer"); + } + } + } + #[cfg(feature = "runtime")] debug!( "Generating bindings, libclang at {}", @@ -768,9 +793,9 @@ impl Bindings { if !explicit_target && !is_host_build { options.clang_args.insert( 0, - format!("--target={}", effective_target).into_boxed_str(), + format!("--target={effective_target}").into_boxed_str(), ); - }; + } fn detect_include_paths(options: &mut BindgenOptions) { if !options.detect_include_paths { @@ -812,19 +837,17 @@ impl Bindings { }; debug!( - "Trying to find clang with flags: {:?}", - clang_args_for_clang_sys + "Trying to find clang with flags: {clang_args_for_clang_sys:?}" ); - let clang = match clang_sys::support::Clang::find( + let Some(clang) = clang_sys::support::Clang::find( None, &clang_args_for_clang_sys, - ) { - None => return, - Some(clang) => clang, + ) else { + return; }; - debug!("Found clang: {:?}", clang); + debug!("Found clang: {clang:?}"); // Whether we are working with C or C++ inputs. let is_cpp = args_are_cpp(&options.clang_args) || @@ -837,7 +860,7 @@ impl Bindings { }; if let Some(search_paths) = search_paths { - for path in search_paths.into_iter() { + for path in search_paths { if let Ok(path) = path.into_os_string().into_string() { options.clang_args.push("-isystem".into()); options.clang_args.push(path.into_boxed_str()); @@ -880,21 +903,19 @@ impl Bindings { if idx != 0 || !options.input_headers.is_empty() { options.clang_args.push("-include".into()); } - options.clang_args.push(f.name.to_str().unwrap().into()) + options.clang_args.push(f.name.to_str().unwrap().into()); } - debug!("Fixed-up options: {:?}", options); + debug!("Fixed-up options: {options:?}"); let time_phases = options.time_phases; - let mut context = BindgenContext::new(options, &input_unsaved_files); + let mut context = BindgenContext::new(options, input_unsaved_files); if is_host_build { debug_assert_eq!( context.target_pointer_size(), - std::mem::size_of::<*mut ()>(), - "{:?} {:?}", - effective_target, - HOST_TARGET + size_of::<*mut ()>(), + "{effective_target:?} {HOST_TARGET:?}" ); } @@ -927,13 +948,13 @@ impl Bindings { if !self.options.disable_header_comment { let version = option_env!("CARGO_PKG_VERSION").unwrap_or("(unknown version)"); - writeln!( + write!( writer, - "/* automatically generated by rust-bindgen {version} */{NL}", + "/* automatically generated by rust-bindgen {version} */{NL}{NL}", )?; } - for line in self.options.raw_lines.iter() { + for line in &self.options.raw_lines { writer.write_all(line.as_bytes())?; writer.write_all(NL.as_bytes())?; } @@ -948,8 +969,7 @@ impl Bindings { } Err(err) => { eprintln!( - "Failed to run rustfmt: {} (non-fatal, continuing)", - err + "Failed to run rustfmt: {err} (non-fatal, continuing)" ); writer.write_all(self.module.to_string().as_bytes())?; } @@ -958,17 +978,17 @@ impl Bindings { } /// Gets the rustfmt path to rustfmt the generated bindings. - fn rustfmt_path(&self) -> io::Result> { + fn rustfmt_path(&self) -> Cow<'_, Path> { debug_assert!(matches!(self.options.formatter, Formatter::Rustfmt)); if let Some(ref p) = self.options.rustfmt_path { - return Ok(Cow::Borrowed(p)); - } - if let Ok(rustfmt) = env::var("RUSTFMT") { - return Ok(Cow::Owned(rustfmt.into())); + Cow::Borrowed(p) + } else if let Ok(rustfmt) = env::var("RUSTFMT") { + Cow::Owned(rustfmt.into()) + } else { + // No rustfmt binary was specified, so assume that the binary is called + // "rustfmt" and that it is in the user's PATH. + Cow::Borrowed(Path::new("rustfmt")) } - // No rustfmt binary was specified, so assume that the binary is called - // "rustfmt" and that it is in the user's PATH. - Ok(Cow::Owned("rustfmt".into())) } /// Formats a token stream with the formatter set up in `BindgenOptions`. @@ -988,7 +1008,7 @@ impl Bindings { Formatter::Rustfmt => (), } - let rustfmt = self.rustfmt_path()?; + let rustfmt = self.rustfmt_path(); let mut cmd = Command::new(&*rustfmt); cmd.stdin(Stdio::piped()).stdout(Stdio::piped()); @@ -1002,6 +1022,12 @@ impl Bindings { cmd.args(["--config-path", path]); } + let edition = self + .options + .rust_edition + .unwrap_or_else(|| self.options.rust_target.latest_edition()); + cmd.args(["--edition", &format!("{edition}")]); + let mut child = cmd.spawn()?; let mut child_stdin = child.stdin.take().unwrap(); let mut child_stdout = child.stdout.take().unwrap(); @@ -1050,7 +1076,7 @@ impl Bindings { } fn rustfmt_non_fatal_error_diagnostic(msg: &str, _options: &BindgenOptions) { - warn!("{}", msg); + warn!("{msg}"); #[cfg(feature = "experimental")] if _options.emit_diagnostics { @@ -1109,7 +1135,7 @@ fn parse(context: &mut BindgenContext) -> Result<(), BindgenError> { use clang_sys::*; let mut error = None; - for d in context.translation_unit().diags().iter() { + for d in &context.translation_unit().diags() { let msg = d.format(); let is_err = d.severity() >= CXDiagnostic_Error; if is_err { @@ -1117,7 +1143,7 @@ fn parse(context: &mut BindgenContext) -> Result<(), BindgenError> { error.push_str(&msg); error.push('\n'); } else { - eprintln!("clang diag: {}", msg); + eprintln!("clang diag: {msg}"); } } @@ -1129,10 +1155,10 @@ fn parse(context: &mut BindgenContext) -> Result<(), BindgenError> { if context.options().emit_ast { fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult { - if !cur.is_builtin() { - clang::ast_dump(cur, 0) - } else { + if cur.is_builtin() { CXChildVisit_Continue + } else { + clang::ast_dump(cur, 0) } } cursor.visit(|cur| dump_if_not_builtin(&cur)); @@ -1140,11 +1166,12 @@ fn parse(context: &mut BindgenContext) -> Result<(), BindgenError> { let root = context.root_module(); context.with_module(root, |ctx| { - cursor.visit_sorted(ctx, |ctx, child| parse_one(ctx, child, None)) + cursor.visit_sorted(ctx, |ctx, child| parse_one(ctx, child, None)); }); - assert!( - context.current_module() == context.root_module(), + assert_eq!( + context.current_module(), + context.root_module(), "How did this happen?" ); Ok(()) @@ -1167,7 +1194,7 @@ pub fn clang_version() -> ClangVersion { let raw_v: String = clang::extract_clang_version(); let split_v: Option> = raw_v .split_whitespace() - .find(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit())) + .find(|t| t.chars().next().is_some_and(|v| v.is_ascii_digit())) .map(|v| v.split('.').collect()); if let Some(v) = split_v { if v.len() >= 2 { @@ -1180,7 +1207,7 @@ pub fn clang_version() -> ClangVersion { }; } } - }; + } ClangVersion { parsed: None, full: raw_v.clone(), @@ -1190,11 +1217,11 @@ pub fn clang_version() -> ClangVersion { fn env_var + AsRef>( parse_callbacks: &[Rc], key: K, -) -> Result { +) -> Result { for callback in parse_callbacks { callback.read_env_var(key.as_ref()); } - std::env::var(key) + env::var(key) } /// Looks for the env var `var_${TARGET}`, and falls back to just `var` when it is not found. @@ -1203,12 +1230,12 @@ fn get_target_dependent_env_var( var: &str, ) -> Option { if let Ok(target) = env_var(parse_callbacks, "TARGET") { - if let Ok(v) = env_var(parse_callbacks, format!("{}_{}", var, target)) { + if let Ok(v) = env_var(parse_callbacks, format!("{var}_{target}")) { return Some(v); } if let Ok(v) = env_var( parse_callbacks, - format!("{}_{}", var, target.replace('-', "_")), + format!("{var}_{}", target.replace('-', "_")), ) { return Some(v); } @@ -1217,7 +1244,7 @@ fn get_target_dependent_env_var( env_var(parse_callbacks, var).ok() } -/// A ParseCallbacks implementation that will act on file includes by echoing a rerun-if-changed +/// A `ParseCallbacks` implementation that will act on file includes by echoing a rerun-if-changed /// line and on env variable usage by echoing a rerun-if-env-changed line /// /// When running inside a `build.rs` script, this can be used to make cargo invalidate the @@ -1270,24 +1297,24 @@ impl Default for CargoCallbacks { impl callbacks::ParseCallbacks for CargoCallbacks { fn header_file(&self, filename: &str) { if self.rerun_on_header_files { - println!("cargo:rerun-if-changed={}", filename); + println!("cargo:rerun-if-changed={filename}"); } } fn include_file(&self, filename: &str) { - println!("cargo:rerun-if-changed={}", filename); + println!("cargo:rerun-if-changed={filename}"); } fn read_env_var(&self, key: &str) { - println!("cargo:rerun-if-env-changed={}", key); + println!("cargo:rerun-if-env-changed={key}"); } } -/// Test command_line_flag function. +/// Test `command_line_flag` function. #[test] fn commandline_flag_unit_test_function() { //Test 1 - let bindings = crate::builder(); + let bindings = builder(); let command_line_flags = bindings.command_line_flags(); let test_cases = [ @@ -1303,7 +1330,7 @@ fn commandline_flag_unit_test_function() { assert!(test_cases.iter().all(|x| command_line_flags.contains(x))); //Test 2 - let bindings = crate::builder() + let bindings = builder() .header("input_header") .allowlist_type("Distinct_Type") .allowlist_function("safe_function"); @@ -1323,7 +1350,7 @@ fn commandline_flag_unit_test_function() { .iter() .map(|&x| x.into()) .collect::>(); - println!("{:?}", command_line_flags); + println!("{command_line_flags:?}"); assert!(test_cases.iter().all(|x| command_line_flags.contains(x))); } @@ -1375,3 +1402,19 @@ fn test_rust_to_clang_target_espidf() { "xtensa-esp32-elf" ); } + +#[test] +fn test_rust_to_clang_target_simulator() { + assert_eq!( + rust_to_clang_target("aarch64-apple-ios-sim").as_ref(), + "arm64-apple-ios-simulator" + ); + assert_eq!( + rust_to_clang_target("aarch64-apple-tvos-sim").as_ref(), + "arm64-apple-tvos-simulator" + ); + assert_eq!( + rust_to_clang_target("aarch64-apple-watchos-sim").as_ref(), + "arm64-apple-watchos-simulator" + ); +} diff --git a/bindgen/log_stubs.rs b/bindgen/log_stubs.rs index 8315983128..51d2f81fd1 100644 --- a/bindgen/log_stubs.rs +++ b/bindgen/log_stubs.rs @@ -1,5 +1,6 @@ #![allow(unused)] +#[clippy::format_args] macro_rules! log { (target: $target:expr, $lvl:expr, $($arg:tt)+) => {{ let _ = $target; @@ -10,22 +11,27 @@ macro_rules! log { let _ = format_args!($($arg)+); }}; } +#[clippy::format_args] macro_rules! error { (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) }; ($($arg:tt)+) => { log!("", $($arg)+) }; } +#[clippy::format_args] macro_rules! warn { (target: $target:expr, $($arg:tt)*) => { log!(target: $target, "", $($arg)*) }; ($($arg:tt)*) => { log!("", $($arg)*) }; } +#[clippy::format_args] macro_rules! info { (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) }; ($($arg:tt)+) => { log!("", $($arg)+) }; } +#[clippy::format_args] macro_rules! debug { (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) }; ($($arg:tt)+) => { log!("", $($arg)+) }; } +#[clippy::format_args] macro_rules! trace { (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) }; ($($arg:tt)+) => { log!("", $($arg)+) }; diff --git a/bindgen/options/as_args.rs b/bindgen/options/as_args.rs index 6918ad9fec..83103fdaf4 100644 --- a/bindgen/options/as_args.rs +++ b/bindgen/options/as_args.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use crate::RegexSet; +use crate::regex_set::RegexSet; /// Trait used to turn [`crate::BindgenOptions`] fields into CLI args. pub(super) trait AsArgs { diff --git a/bindgen-cli/options.rs b/bindgen/options/cli.rs similarity index 69% rename from bindgen-cli/options.rs rename to bindgen/options/cli.rs index 5311d87aa7..972b487c25 100644 --- a/bindgen-cli/options.rs +++ b/bindgen/options/cli.rs @@ -1,26 +1,37 @@ -use bindgen::callbacks::TypeKind; -use bindgen::{ - builder, Abi, AliasVariation, Builder, CodegenConfig, EnumVariation, +#![allow(unused_qualifications)] // Clap somehow generates a lot of these + +use crate::{ + builder, + callbacks::{ + AttributeInfo, DeriveInfo, ItemInfo, ParseCallbacks, TypeKind, + }, + features::{RustEdition, EARLIEST_STABLE_RUST}, + regex_set::RegexSet, + Abi, AliasVariation, Builder, CodegenConfig, EnumVariation, FieldVisibilityKind, Formatter, MacroTypeVariation, NonCopyUnionStyle, - RegexSet, RustTarget, DEFAULT_ANON_FIELDS_PREFIX, RUST_TARGET_STRINGS, + RustTarget, +}; +use clap::{ + error::{Error, ErrorKind}, + CommandFactory, Parser, }; -use clap::error::{Error, ErrorKind}; -use clap::{CommandFactory, Parser}; use proc_macro2::TokenStream; -use std::fs::File; use std::io; use std::path::{Path, PathBuf}; -use std::process::exit; use std::str::FromStr; +use std::{fs::File, process::exit}; fn rust_target_help() -> String { format!( - "Version of the Rust compiler to target. Valid options are: {:?}. Defaults to {}.", - RUST_TARGET_STRINGS, + "Version of the Rust compiler to target. Any Rust version after {EARLIEST_STABLE_RUST} is supported. Defaults to {}.", RustTarget::default() ) } +fn rust_edition_help() -> String { + format!("Rust edition to target. Defaults to the latest edition supported by the chosen Rust target. Possible values: ({}). ", RustEdition::ALL.map(|e| e.to_string()).join("|")) +} + fn parse_codegen_config( what_to_generate: &str, ) -> Result { @@ -36,7 +47,7 @@ fn parse_codegen_config( otherwise => { return Err(Error::raw( ErrorKind::InvalidValue, - format!("Unknown codegen item kind: {}", otherwise), + format!("Unknown codegen item kind: {otherwise}"), )); } } @@ -132,6 +143,7 @@ fn parse_custom_attribute( override_usage = "bindgen